Реакция использованияСостояния нарушена? состояние не обновляется правильно - PullRequest
1 голос
/ 21 апреля 2020

см. Здесь:

https://codesandbox.io/s/nervous-hermann-5wsph

в основном:

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

исправляется после нажатия клавиши Shift на клавиатуре. Но кроме этого? клавиатура onKeyPress имеет неверные useState переменные.

в чем проблема?

Это: enter image description here

предполагается отладочный текст изменить в консоли, но не. Это означает, что все, что я запускаю onKeyPress, будет иметь неправильную копию переменных состояния, кроме тех, которые я вызываю в обратном вызове.

Это просто очень, очень плохо. Я думал useState решит эти проблемы, а не сделает их сложнее ?! Я что-то упустил?

1 Ответ

3 голосов
/ 21 апреля 2020

Проблема не в состоянии React, а в компоненте Keyboard.

react-simple-keyboard не осознает, что реквизиты изменились, поэтому передаваемая им функция onKeyPress всегда имеет начальное значение .

При изменении состояния React (текст отладки) ваша функция onKeyPressed в компоненте MyComponent будет воссоздана с новыми значениями. В свою очередь, функция onKeyPress внутри вашего KeyboardWrapper также воссоздается.

Эта новая функция передается как опора для Keyboard, но в исходном коде для Keyboard ( см. здесь ) выполняется проверка, чтобы увидеть, изменились ли реквизиты.

Функция, которая выполняет эту проверку, может быть найдена здесь :

export const propsChanged = (prevProps, props) => {
  const cleanProps = sourceObj =>
    JSON.stringify({
      ...sourceObj,
      stateToIgnore: null
    });

  return cleanProps(props) !== cleanProps(prevProps);
};

Это функция имеет ошибку. Когда реквизиты «очищены», все функции удаляются, что немного глупо, поскольку функция является допустимым реквизитом.

Так что предыдущие реквизиты (включая вашу старую функцию onKeyPress с начальным значением из debugText) «очищается» и сравнивается с новыми «очищенными» реквизитами, и Keyboard считает, что реквизиты не изменились, поскольку ни предыдущие clean реквизиты, ни новые clean реквизиты не имеют onKeyPress функция.

Я добавил некоторые записи в эту функцию:

const previousProps = {
  onKeyPress: () => {
    console.log("Initial text");
  },
};

const newProps = {
  onKeyPress: () => {
    console.log("New text");
  },
};

const propsChanged = (prevProps, props) => {
  const cleanProps = (sourceObj) =>
    JSON.stringify({
      ...sourceObj,
      stateToIgnore: null,
    });

  console.log("original prev props:", prevProps);
  console.log("clean prev props:", cleanProps(prevProps));
  console.log("original new props:", props);
  console.log("clean new props:", cleanProps(props));

  return cleanProps(props) !== cleanProps(prevProps);
};

console.log(
  "does keyboard think props have changed?",
  propsChanged(previousProps, newProps)
);

console.log("have props actually changed?", previousProps !== newProps);

console.log("is there a bug with react-simple-keyboard?", true);

и вот результат:

original prev props: { onKeyPress: [Function: onKeyPress] }
clean prev props: {"stateToIgnore":null}
original new props: { onKeyPress: [Function: onKeyPress] }
clean new props: {"stateToIgnore":null}
does keyboard think props have changed? false
have props actually changed? true
is there a bug with react-simple-keyboard? true

Я предлагаю подать вопрос по на их репозиторий GitHub .

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