Почему мой вложенный компонент восстанавливается сам? - PullRequest
0 голосов
/ 05 мая 2019

Я пытаюсь создать собственный слайдер, основанный на элементе ввода / диапазона. Суммированный код выглядит примерно так:

const Slider = ({ className, backgroundColor, ...inputAttributes }) => {
  const [value, setValue] = useState(5);

  const handleSliderChange = event => {
    setValue(event.currentTarget.value);
  };

  const SliderElement = () => (
    <input value={value} onChange={handleSliderChange} {...inputAttributes} />
  );

  // ...

  return (
    <>
      <SliderElement />
      <p>
        <Display>{value}</Display>
      </p>
    </>
  );
};

Это называется так:

<Slider type="range" min={1} max={10} step={1} />

Полный рабочий код здесь: https://codesandbox.io/s/000qm47pjw

с вложенным компонентом SliderElement

Используя приведенный выше код, я могу перемещать ползунок только на один шаг за раз (мне нужно «отжать» ползунок и щелкнуть по нему еще раз для следующего шага). Я подозреваю, что это потому, что SliderElement перерисовывается каждый раз, когда я перемещаю ползунок.

Однако ...

Если я вообще пропущу SliderElement и вставлю <input... прямо в возвращенный JSX, он будет работать безупречно.

Полный рабочий код здесь: https://codesandbox.io/s/5469y582yn

без вложенного компонента SliderElement


Почему SliderElement перерисовывается каждый раз, когда я его использую (при условии, что это так)?

Как мне сохранить <input..., вложенным во вложенный компонент, и при этом обеспечить бесперебойную работу?

1 Ответ

2 голосов
/ 05 мая 2019

Различают эти два:

var aReactElement = <input />
var aReactComponent = () => <input />

Реактивный компонент отвечает за решение, должен ли он повторно визуализировать реактивные элементы, которыми он управляет.Он работает в одном предположении, компонентный объект экземпляр должен оставаться неизменным, чтобы служить ключом ссылки для части сохраняющегося состояния.

В вашем примере экземпляр SliderElementпостоянно меняется при каждом повторном рендере Slider, это новая функция каждый раз.Таким образом, ваше дерево DOM постоянно размонтируется, а затем монтирует элемент <input />.

Вместо того, чтобы SliderElement сделать компонентом, вы можете сделать его элементом.

const SliderElement = (
    <input value={value} onChange={handleSliderChange} {...inputAttributes} />
  );

  // ...

  return (
    <>
      {SliderElement}
      <p>
        <Display>{value}</Display>
      </p>
    </>
  );
...