如何在自定义钩子中创建一个组件,该钩子保存该组件的状态?
我的尝试基本上可以做正确的事,但是拖放操作没有按预期进行。相反,滑块将仅更改点击值。我认为问题在于,useState挂钩在X
定义之外被调用。但是我们如何在一个挂钩中创建一个组件,然后在需要处理其余挂钩中该内部组件的状态的地方?
https://codesandbox.io/s/material-demo-milu3?file=/demo.js:0-391
import React from "react";
import Slider from "@material-ui/core/Slider";
function useComp() {
const [value, setValue] = React.useState(30);
const X = () => <Slider value={value} onChange={(_, v) => setValue(v)} />;
return { X, value };
}
export default function ContinuousSlider() {
const { X, value } = useComp();
return (
<div>
{value}
<X />
</div>
);
}
答案 0 :(得分:2)
每当在每个渲染上调用自定义钩子时,都会创建一个新的Slider(Broken
)组件。由于创建了新组件,因此也会重新创建事件处理程序,并且取消拖动。您可以通过两种方式解决此问题:
将组件包装在useCallback()
中,并在渲染组件(sandbox)时传递value
:
const Broken = useCallback(({ value }) => (
<Slider value={value} onChange={changeHandler} />
), [changeHandler]);
// usage
<Broken value={broken} />
呈现挂钩中的组件,并使用将其包含在组件(sandbox)中:
function useComp() {
const [broken, setBroken] = React.useState(30);
const changeHandler = useCallback((_, v) => setBroken(v), []);
const slider = <Slider value={broken} onChange={changeHandler} />;
return { slider, broken };
}
// usage
<div>
Broken: {broken}
{slider}
OK: {ok}
<Slider value={ok} onChange={(_, v) => setOk(v)} />
</div>