查看此处:
https://codesandbox.io/s/nervous-hermann-5wsph
基本上:
示例中使用的键盘似乎得到了错误的状态副本
一旦按键盘上的shift键,它便会修复。但是除此之外呢?键盘onKeyPress的useState
变量错误。
出什么问题了?
调试文本应该在控制台中更改,但不会更改。这意味着我启动onKeyPress的任何内容都将具有错误的状态变量副本,但我在回调中调用的除外。
那是非常非常糟糕。我以为useState
将解决这些问题,而不是让它们变得更难?我想念什么吗?
答案 0 :(得分:3)
问题不是与React状态有关,而是与Keyboard
组件有关。
react-simple-keyboard
并未意识到道具已经更改,因此您传递的onKeyPress
函数始终具有初始值。
当React状态更改(调试文本)时,将使用新值重新创建onKeyPressed
组件中的MyComponent
函数。反过来,onKeyPress
内部的KeyboardWrapper
函数也会重新创建。
此新功能作为道具传递给Keyboard
,但是在Keyboard
(see here)的源代码中进行检查以查看道具是否已更改。>
执行此检查的功能可以在here中找到:
export const propsChanged = (prevProps, props) => {
const cleanProps = sourceObj =>
JSON.stringify({
...sourceObj,
stateToIgnore: null
});
return cleanProps(props) !== cleanProps(prevProps);
};
此功能有一个错误。当“清理”道具时,所有功能都将被删除-这有点愚蠢,因为功能是有效的道具。
因此,先前的道具(包括旧的onKeyPress
函数,其初始值为debugText
)被“清理”并与新的“清理的”道具进行比较,它看起来{ 1}},因为先前的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);
我建议在their github repo上提出问题。