React Hooks будет рендериться несколько раз после ожидания - PullRequest
0 голосов
/ 24 апреля 2020
const [ html, setHTML ] = useState('');
const [ script, setScript ] = useState('');

const update = (script, html) => {
  setScript(script);
  setHTML(html);
};

update('a', 'b'); // actual code in an event handler

Приведенный выше код работает нормально, React Hooks отрисовывает ОДИН РАЗ и объединяет setScript & setHTML;

const [ html, setHTML ] = useState('');
const [ script, setScript ] = useState('');

const update = async (script, html) => {
  await new Promise(resolve => setTimeout(resolve, 10));
  setScript(script);
  setHTML(html);
};

update('a', 'b'); // actual code in an event handler

Приведенный выше код больше не работает, React Hooks отрисовывает ДВАЖДЫ, и он не ' t объединить setScript & set HTML.

Я могу изменить на код:

const [ state, setState ] = useState({
  html: '',
  script: ''
});

const update = async (script, html) => {
  await new Promise(resolve => setTimeout(resolve, 10));
  setState({
    script,
    html
  });
};

update('a', 'b'); // actual code in an event handler

Приведенный выше код отображает только ОДИН РАЗ, но в нем есть новая ошибка: курсор в textArea (где скрипт и html go) переместятся в конец textArea вместо того, чтобы оставаться там, где он находится.

1 Ответ

0 голосов
/ 24 апреля 2020

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

import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';

// ....

const [ html, setHTML ] = useState('');
const [ script, setScript ] = useState('');

const update = async (script, html) => {
  await new Promise(resolve => setTimeout(resolve, 10));
    batchedUpdates(() => {
        setScript(script);
        setHTML(html);
    });
};

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