In my application I have component like that:
const MyComponent = props => {
const { attrOneDefault, attrTwoDefault, formControl } = props;
const [inputValue, setInputValue] = useState({
attr_one: attrOneDefault,
attr_two: attrTwoDefault
});
const getValue = ( attr ) => {
return inputValue[attr];
}
const setValue = ( attr, val ) => {
if( attr === 'attr_one' ) {
if( val === 'bar' && getValue(attr) !== 'foo' ) {
val = 'foo bar';
}
}
setInputValue( {...inputValue, [attr]: val} );
}
useEffect( () => {
if( formControl ) {
Object.keys(inputValue).forEach( attribute => {
formControl.subscribeToValueCollecting( attribute, () => {
return getValue(attribute);
});
formControl.subscribeToValueChange( attribute, ( value ) => {
setValue( attribute, value );
return true;
});
});
}
return () => {
if( formControl ) {
Object.keys(inputValue).forEach( attribute => formControl.unsubscribe(attribute) );
}
}
}, []);
return (
<div class="form-field">
<input
type="text"
value={getValue('attr_one')}
onChange={ e => setValue('attr_one', e.target.value)}
/>
<input
type="checkbox"
checked={getValue('attr_two')}
onChange={ e => setValue('attr_two', !!e.target.checked)}
/>
</div>
);
}
And inside functions setValue and getValue I always have default values in inputValue - I can't get updated state inside this functions. How i can organize my code to solve this problem?
P. S.
1) With useCallback I have the same results:
const getValue = useCallback( ( attr ) => {
return inputValue[attr];
}, [inputValue]);
const setValue = useCallback( ( attr, val ) => {
if( attr === 'attr_one' ) {
if( val === 'bar' && getValue(attr) !== 'foo' ) {
val = 'foo bar';
}
}
setInputValue( {...inputValue, [attr]: val} );
}, [inputValue]);
2) With useEffect functions setValue and getValue are unavailable at first render:
let getValue, setValue;
useEffect( () => {
getValue = ( attr ) => {
return inputValue[attr];
}
setValue = ( attr, val ) => {
if( attr === 'attr_one' ) {
if( val === 'bar' && getValue(attr) !== 'foo' ) {
val = 'foo bar';
}
}
setInputValue( {...inputValue, [attr]: val} );
}
}, [inputValue]);
setValue()have seemingly random logic in it?useEffectis capturing yourinputValue, that's why it's always the same. Try passinginputValueinto your use effect array[]