0

In my app I have 2 components, looking like this:

  1. Child component
import React, { useState, useImperativeHandle } from 'react'

const Child = React.forwardRef(({props}, ref) => {
  const [loading, setLoading] = useState(false)
  const [text, setText] = useState('')

  const increment = () => {
    setLoading(true)
    sayHello()
    console.log(text)
    setLoading(false)
  }

  const sayHello = () => {
    const string = 'hello'
    setText(string)
  }

  useImperativeHandle(ref, () => ({
    increment
  }))

  return (
    <div>
      {loading ? <div>Loading...</div> : null}
      <h4>Child component</h4>
    </div>
  )
})

export default Child
  1. Parent component
import React, { useRef } from 'react'
import Child from './Child'

function Parent() {
  const childComponent = useRef();

  return (
    <div>
      <h1>Parent</h1>
      <Child ref={childComponent}/>
      <button onClick={(e)=>{e.preventDefault(); childComponent.current.increment()}}>Click me</button>      
    </div>
  )
}

export default Parent

What I am trying to achieve is to call a Child component method and get the text value displayed which is set in Child state.

Instead, when executing the increment() function the first time the console prints an empty string. Only on second button press it prints 'hello'.

What am I doing wrong?

Viktor
  • 11
  • 2
  • You are updating the state, so console logging it in the same render cycle only logs the current state value, ***not*** what it will be updated to on a subsequent render cycle. Using the `useEffect` hook allows you to console log the value *after* state updates. – Drew Reese Oct 20 '21 at 17:21

0 Answers0