Ваш императивный дескриптор в FilterFather
не требуется. Он ничего не добавляет / не удаляет на ручку. Вы можете просто переслать его напрямую:
const FilterFather = (_, ref) => {
return <Filter ref={ref} />;
};
Also there is a problem with it because it will not update correctly.
useImperativeHandle(ref, () => ({
name: filterRef.current.name,
age: filterRef.current.age,
}), [filterRef]) // this will not update correctly
You passed filterRef
as a dependency but filterRef
is static and will not change even when filterRef.current.name
or filterRef.current.age
changes.
Note that useImperativeHandle
is not supposed to be used to read state from child components. It is actually discouraged to use any kind of imperative methods in react except there is no other way. This is most of the time the case if you work with 3rd party libraries that are imperative in nature.
EDIT:
Given your updated code the react way to do that is to lift state up. It doesn't require any refs:
export default function App() {
const [values, setValues] = useState({
name: "lewis",
age: 18
});
const handleChange = useCallback(
(key, value) => setValues(current => ({ ...current, [key]: value })),
[]
);
return (
console.log (values.name, values.age)}> щелкните меня ); }
const FilterFather = props => {
return (
<>
<Filter label="Name" name="name" {...props} />
<Filter label="Age" name="age" {...props} />
</>
);
};
const Filter = ({ label, name, values, onChange }) => {
const handleChange = useCallback(e => onChange(name, e.target.value), [
name,
onChange
]);
return (
<>
<div>
<label>{label}:</label>
<input value={values[name]} onChange={handleChange} />
</div>
</>
);
};
Изменить useImperativeHandle