gpt4 book ai didi

reactjs - 多层 forwardRef 和 useImperativeHandle

转载 作者:行者123 更新时间:2023-12-04 04:02:27 26 4
gpt4 key购买 nike

我需要使用 ref获取孙组件的状态,我使用 useImperativeHandle 对其进行了自定义,简化了整个代码
here .

function App() {
const ref = useRef(null);
return (
<div className="App">
<button
onClick={() => console.log(ref.current.name, ref.current.age)}
>click me</button>
<FilterFather ref={ref} />
</div>
);
}

const FilterFather = (_, ref) => {
const filter1Ref = useRef(null);
const filter2Ref = useRef(null);
useImperativeHandle(ref, () => ({
name: filter1Ref.current.name,
age: filter2Ref.current.age,
}))
return (
<>
<Filter1 ref={filter1Ref}/>
<Filter2 ref={filter2Ref} />
</>
)
}
export default forwardRef(FilterFather);
const Filter1 = (props, ref) => {
const [name, setName] = useState('lewis')
useImperativeHandle(ref, () => ({
name
}), [name])
return (
<>
<div>
name:
<input
value={name}
onChange={e => setName(e.target.value)}
/>
</div>
</>
)
}
const Filter2 = (props, ref) => {
const [age, setAge] = useState(18)
useImperativeHandle(ref, () => ({
age
}), [age])
return (
<>
<div>
age:
<input
value={age}
onChange={e => setAge(e.target.value)}
/>
</div>
</>
)
}
export default {
Filter1: forwardRef(Filter1),
Filter2: forwardRef(Filter2),
}
一层 forwardRefuseImperativeHandle工作正常,两层出错

最佳答案

您在 FilterFather 中的命令式句柄不需要。它不会向 handle 添加/删除任何东西。您可以直接转发它:

const FilterFather = (_, ref) => {
return <Filter ref={ref} />;
};
Edit useImperativeHandle
它也有一个问题,因为它不会正确更新。
useImperativeHandle(ref, () => ({
name: filterRef.current.name,
age: filterRef.current.age,
}), [filterRef]) // this will not update correctly
您通过了 filterRef作为依赖项,但 filterRef是静态的,即使在 filterRef.current.name 时也不会改变或 filterRef.current.age变化。
请注意 useImperativeHandle不应用于从子组件读取状态。实际上不鼓励在 react 中使用任何类型的命令式方法,除非没有其他方法。如果您使用本质上必不可少的 3rd 方库,则大多数情况下都是这种情况。
编辑 :
鉴于您更新的代码,这样做的 react 方式是提升状态。它不需要任何引用:
export default function App() {
const [values, setValues] = useState({
name: "lewis",
age: 18
});

const handleChange = useCallback(
(key, value) => setValues(current => ({ ...current, [key]: value })),
[]
);

return (
<div className="App">
<button onClick={() => console.log(values.name, values.age)}>
click me
</button>
<FilterFather values={values} onChange={handleChange} />
</div>
);
}
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>
</>
);
};
Edit useImperativeHandle

关于reactjs - 多层 forwardRef 和 useImperativeHandle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62871875/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com