【问题标题】:How to create a component in a custom hook that handles state within the hook?如何在自定义钩子中创建一个处理钩子内状态的组件?
【发布时间】:2020-07-22 14:44:51
【问题描述】:

如何在自定义挂钩中创建组件,其中挂钩保存组件的状态?

我的尝试基本上是正确的,但是拖放没有按预期工作。相反,滑块将仅更改点击时的值。我认为问题在于,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>
  );
}

【问题讨论】:

  • @GalAbra 虽然根本问题是相同的(在重新渲染时丢失事件处理程序),但为另一个问题提供的解决方案对我来说没有帮助,因为我依赖钩子来做更多事情逻辑,而解决方案建议不使用钩子。

标签: reactjs material-ui react-hooks


【解决方案1】:

每当调用自定义挂钩时(在每次渲染上),都会创建一个新的 Slider (Broken) 组件。由于创建了一个新组件,因此也重新创建了事件处理程序,并且取消了拖动。您可以通过两种方式解决此问题:

将组件包裹在useCallback()中,并在渲染组件时传递valuesandbox):

  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>

【讨论】:

  • 谢谢。根据您的回答,我能够解决我的实际问题。我还需要该钩子根据自定义钩子useComp(type) 的参数创建不同的组件,为此我还需要一个useMemo 用于决定创建哪个组件的逻辑Fixed = useMemo(() =&gt; { switch(type) {... &lt;Slider chaneValue={setValueCallback} ... });
  • 哦,特别感谢您提供 2 个解决方案。另一个相关问题也提供了第三种解决方案,根本不使用钩子。
  • 不客气。实际上,相关问题的答案是我通常会使用的答案。但是,在某些特殊情况下,您实际上需要在挂钩或其他函数中创建自定义组件。
猜你喜欢
  • 2020-08-04
  • 2022-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
  • 2021-06-02
  • 1970-01-01
  • 2020-08-28
相关资源
最近更新 更多