Как создать компонент в пользовательском хуке, который обрабатывает состояние в хуке? - PullRequest
2 голосов
/ 10 апреля 2020

Как я могу создать компонент в пользовательском хуке, где хук удерживает состояние для компонента?

Моя попытка в основном делает правильно, но перетаскивание не работает, как ожидалось. Вместо этого ползунок изменит значение только при нажатии . Я думаю, что проблема в том, что хук useState вызывается вне определения X. Но как мы можем создать компонент в хуке тогда, когда мне нужно работать с состоянием этого внутреннего компонента в остальной части хука?

enter image description here

https://codesandbox.io/s/material-demo-milu3?file= / демо. 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 Ответ

2 голосов
/ 10 апреля 2020

Каждый раз, когда вызывается пользовательский хук (для каждого рендера), создается новый компонент Slider (Broken). Поскольку новый компонент создан, обработчики событий также воссоздаются, и перетаскивание отменяется. Вы можете решить эту проблему двумя способами:

Заверните компонент в useCallback() и передайте value при рендеринге компонента ( песочница ):

  const Broken = useCallback(({ value }) => (
    <Slider value={value} onChange={changeHandler} />
  ), [changeHandler]);

  // usage
  <Broken value={broken} />

Визуализация компонента в хуке и использование включения его в компонент ( песочница ):

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>
...