我一直在为一个类做一个简单的react-redux todo示例,每次检查时都会在控制台中显示几条警告消息,并取消选中复选框输入。
您可以在以下图片中看到警告。
我也在谷歌搜索警告信息,但找不到任何有效的解决方案。另外,我的注意力是看起来它试图访问本机事件和DOM元素的每个属性。
这是具有输入复选框
的演示组件的代码class TodoItem extends React.Component {
state = {
isChecked: false
};
handleCheckbox = () => {
this.setState({
isChecked: !this.state.isChecked
});
};
render() {
const { todos, onItemClick } = this.props;
const { isChecked } = this.state;
return (
<div>
<ul>
{todos.map((todo, id) => {
return (
<li key={id} onClick={onItemClick}>
<input
onChange={this.handleCheckbox}
type="checkbox"
checked={isChecked}
/>
<label>
<span />
{todo.textInput}
</label>
</li>
);
})}
</ul>
</div>
);
}
}
export default TodoItem;
我也在CodeSandbox上传了示例:https://codesandbox.io/s/k0mlxk1yqv
如果要复制此错误,则需要将项目添加到待办事项列表,然后单击复选框以选中并取消选中几次。
如果有人知道为什么这个警告标志不断出现以及如何禁用它们,我将非常感谢您的投入:)
答案 0 :(得分:8)
我建议尝试两种解决方案:
第一次更改
onChange={this.handleCheckbox}
到
onChange={() => this.handleCheckbox}
如果这行不通,请在“ handleCheckbox”中添加此行
handleCheckbox = (event) => {
event.persist();
this.setState({
isChecked: !this.state.isChecked
});};
答案 1 :(得分:3)
这可能有点晚了,但是我遇到了同样的问题,并且以某种方式解决,我认为这可能比亚当·奥尔洛夫的答案更好。我不认为这两个答案都直接适用于所问的问题,但是在搜索有关合成事件和复选框时会出现此问题,因此它和其他任何地方一样好...
我相信Adam是正确的,因为他相信React会清除SyntheticEvent对象的所有属性(这很有意义,因为React告诉我们它正在重用该对象)。
但是,除非您需要整个对象,否则我认为调用event.persist()并不是最好的解决方案,根据documentation所述,它将从池中删除该对象(大概是它们放了是有充分理由的。)
如果要以异步方式访问事件属性,则应在事件上调用event.persist(),这将从池中删除综合事件,并允许用户代码保留对事件的引用。
除了这样做,如果您只需要事件对象中的一个或两个值,则可以将它们分配给局部变量,然后在自己的函数内引用局部变量,如下所示:
<input type="checkbox" onChange={(event) => {
let checked = event.currentTarget.checked; //store whatever values we need from from the event here
this._someOtherFunction(checked)
} />
通过这种方式,您不必以任何方式重组代码来避免进行任何依赖于事件数据的异步操作,并且您也不必担心潜在的性能影响,因为您可以让React执行操作它想要事件池。
答案 2 :(得分:3)
就我而言,我有以下代码:
handleInput (inputName) {
return e => {
this.setState(state => ({ // <-- asynchronous call
data: {
...state.data,
[inputName]: e.target.value // <-- this was causing the warnings
}
}));
}
}
然后我将其更改为:
handleInput (inputName) {
return e => {
const { value } = e.target; // <-- moved outside asynchronous context
this.setState(state => ({
data: {
...state.data,
[inputName]: value
}
}));
}
}
答案 3 :(得分:2)
尽管我的设置是类似的问题,但我的设置是功能组件,材质UI <Textform />
输入。
上面提到event.persist();
的那个人,谢谢你为我工作,但是第一个建议没有明显影响,不确定那是否是因为Im使用功能组件而不是类组件。 (我不再使用类组件,仅使用钩子即可使用
还请注意建议使用event.persist()的警告信息。我的问题是我正在使用onChange捕获表单输入并将输入存储到我的状态中,大约在第二个或第三个字符之后,它将引发错误并使我的应用程序崩溃。
之前:
const handleChange = (e) => {
setState((form) => ({
...form,
[e.target.name]: e.target.value,
}));
};
之后:
const handleChange = (e) => {
e.persist();
setState((form) => ({
...form,
[e.target.name]: e.target.value,
}));
};
因此,这似乎是对类似问题的正确解决方案,虽然我没有使用复选框,但我使用的是表单输入,即Material-UI <TextField />
。我可以删除
e.persist();
并且代码将再次失败,将其重新添加,一切都很好,没有崩溃也没有警告。
答案 4 :(得分:0)
针对那些通过本机反应解决此问题的人。
我在导航中遇到了这个问题
PersonalProductsScreen.navigationOptions=({navigation})=>{
const handleEditButton=navigation.navigate.bind(this,"EditProduct")
return {
headerTitle:"My Products",
headerRight:<CustomHeaderButton
iconName="ios-add"
title="Add"
iconSize={26}
color={colors.bright}
onPress={handleEditButton}
/>
}
}
注意我使用的方法。 我正在尝试绑定导航方法。
这是重构:
const handleAddButton=()=>navigation.navigate("EditProduct")