I'm maintaining a legacy Class based React project and introducing functional components in as I go. One of the workarounds to try to avoid a total rewrite is to allow child components to communicate with parents via a 'registration' model where the child registers itself with the parent and the parent calls child functions.
My problem is that the child state seems to become inaccessible to the parent ( Calling the 'getChildValue()' function always returns the initial child state.)
I guess in a class based world, I'd just bind(this) to the function and it would work.
Can anyone help:
A pen illustrating the problem is here:
https://codepen.io/seven360/pen/NWaEjmW
Clicking the 'Inc Value In Child' increments the state, but the 'Get Value From Child' always returns 1 (the initial state)
const ChildElement = (props) =>
{
const [ value, setValue ] = useState ( 1 ) ;
const getValue = () =>
{
console.log ( "getValue Called");
return value ;
}
useEffect(() => {
props.register ( {
getValue: getValue
}) ;
}, [] ) ;
const incChildValue = () =>
{
setValue ((value) => value + 1);
}
return <div>
<h1>Child Component Value Currently = {value}</h1>
<button type='button' onClick={incChildValue} >Inc Value In Child</button>
</div>
}
And this is the parent 'legacy' container:
class Container extends React.Component
{
constructor ( props )
{
super(props) ;
this.register = this.register.bind(this) ;
this.getChildValue = this.getChildValue.bind(this);
this.childRef = React.createRef();
}
register ( childFuncs )
{
console.log ( "Registered");
console.log ( childFuncs );
this.childRef.current = childFuncs ;
}
getChildValue ()
{
const childValue = this.childRef.current.getValue() ;
alert ( "This Should not be 1 - " + childValue );
}
render()
{
return (
<div>
<div>Container</div>
<ChildElement register={this.register} />
<button type='button' onClick={this.getChildValue} >Get Value From Child</button>
</div>
)
}
}