Kyano
Kyano

Reputation: 184

Return value from child component to parent component React

So I'm trying to use a react Timer in one of my class components. I figured out how to connect it, but now I need to save the time into the parent's state. How can I go upon doing that? Since the time is being measured on the child component. So essentially I need to save the time measured from the child component to the parent's state.

Upvotes: 3

Views: 6929

Answers (3)

Ben Aston
Ben Aston

Reputation: 55729

The following defines two React components: Parent and Child.

Parent declares a piece of state named time and a mutator method for that state named setTime.

The current value of time is passed to Child via the prop named time.

setTime is passed to Child via the prop named notify.

Child configures a timer that invokes notify (ie setTime) once a second.

Invoking notify tells React that a state change has occurred and triggers a re-rendering of both components, causing the time to be rendered by each component, once every second.

pre { border: 1px solid black; padding: 10px; }
<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

<script type="text/babel">
const { useState, useEffect } = React

const Parent = () => {
  const [ time, setTime ] = React.useState('--- --- -- ----')
  return <pre>
           Parent: { time }
           <Child notify={setTime} time={ time }/>
         </pre>
}

const Child = ({ notify, time }) => {    
    useEffect(()=>{
      const id = setInterval(() => notify(Date()), 1000)
      return () => clearInterval(id)      
    })

    return <pre>Child: {time}</pre>
}

ReactDOM.render(<Parent/>, document.querySelector('main'))
</script>
<main></main>

Upvotes: 1

GabrielMC
GabrielMC

Reputation: 288

You'll need to pass a function that updates the parent's state to the child component via props:

In this particular example, both the child and the parent props have a state hook that keeps track of time - the parent's updateParentTime function get's called any time the child's time value changes.

NOTE: it's probably not necessary to keep state in both places...I was just showing an example. If the parent needs has state for time, you could also just pass that down to the child component

const Parent = (props) => {
   const [time, setTime] = useState(0);

   const updateParentTime = (t) => {
      setTime(t);
   }
 
  return (
    <Child updateParentTime={updateParentTime}/>
  )
}

const Child = (props) => {
   const {updateParentTime} = props;
   const [time, setTime] = useState(0);

   useEffect(() => {
      updateParentTime(time)
   }, [time]);

   return (
     <div>
       {/* something goes here */}
     </div>
   )
}

Upvotes: 1

seedBoot
seedBoot

Reputation: 394

The phrase that comes to mind is Lifting State up. React has a 'top-down' data flow. So your state needs to be initialised in the parent component and passed down to the child components that need it. e.g. (pseudocode, may not work)

function Parent() {
  const [text, setText] = useState('hello world')

  return (
    <>
      <Child text={text} />
      <OtherChild text={text} setText={setText} />
    </>
  )  
}

function Child({ text }) {
  return <p>{text}</p>
}

function OtherChild({ text, setText }) {
  return (
    <input
      onChange={e => setText(e.target.value)}
      value={text} />
  )
}

Upvotes: 3

Related Questions