如何在自定义钩子中创建处理钩子中状态的组件?

时间:2020-04-09 21:16:42

标签: reactjs material-ui react-hooks

如何在自定义钩子中创建一个组件,该钩子保存该组件的状态?

我的尝试基本上可以做正确的事,但是拖放操作没有按预期进行。相反,滑块将仅更改点击值。我认为问题在于,useState挂钩在X定义之外被调用。但是我们如何在一个挂钩中创建一个组件,然后在需要处理其余挂钩中该内部组件的状态的地方?

enter image description here

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>
  );
}

1 个答案:

答案 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>