Вложенные реагирующие крючки, выставляющие ссылки c - PullRequest
2 голосов
/ 25 марта 2020

Я искал реализацию eslint-plugin-Reaction-hooks , и похоже, что функции useState * setState и useReducer * dispatch являются статическими c ссылками которые не требуется объявлять в массиве зависимостей в useEffect.

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

const useCustom = () => {
    const [number, setNumber] = React.useState(0);
    return [number, setNumber];
};

, который затем используется следующим образом:

const [number, setNumber] = useCustom();
React.useEffect(() => {
   if (something) {
       setNumber(1);
   }
}, [something]); // useEffect has a missing dependency: 'setNumber'

Добавление зависимости к массиву, по-видимому, не вызывает дополнительных циклов рендеринга. Однако возникает другой вопрос: Что если мой хук вернет ссылку на значение, возвращаемое из useRef(), было бы безопасно добавить его в массив зависимостей?

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Значение от useRef никогда не изменится, если вы не размонтируете и не перемонтируете компонент.

Изменение значения value.current не приведет к повторной визуализации компонента, но если значение value.current является зависимостью вашего эффекта, то ваш эффект будет запущен повторно при повторной визуализации компонента.

Не уверен если это отвечает на ваш вопрос, я добавил пример кода ниже, чтобы продемонстрировать:

const useTimesRendered = () => {
  const rendered = React.useRef(0);
  rendered.current++;
  return rendered;
};
const useCustomRef = () => {
  const customRef = React.useRef(0);
  return customRef;
};
const App = () => {
  const rendered = useTimesRendered();
  const custom = useCustomRef();
  const [, reRender] = React.useState({});
  React.useEffect(
    () => console.log('rendered ref only on mount', rendered.current),
    [rendered]
  );
  const customVal = custom.current;
  React.useEffect(
    () => console.log('custom ref.current only when re rendering', customVal),
    [customVal]
  );
  return (
    <div>
      <h1>Times rendered: {rendered.current}</h1>
      <button onClick={() => custom.current++}>
        increase custom
      </button>
      <button onClick={() => reRender({})}>
        Re render app
      </button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
0 голосов
/ 25 марта 2020

Если я правильно понял ваш вопрос, тогда go будет с да. Если ref никогда не изменяется (захватывает какой-либо узел при монтировании компонента), или если он изменяется произвольно (как в usePrevious hook), он должен быть добавлен в список зависимостей. Единственная потенциальная проблема, о которой я мог подумать, - это когда кто-то, например, использует ref для ввода, а затем ожидает, что получит новый обновленный ref после somenthing типа пользователя. Но это топи c в другое время

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...