我正在开发一个简单的待办事项列表反应应用程序(新的React.js)。我已经将项目添加到工作列表中,但删除项目会引起一个问题。在我的父反应组件中,我有以下代码:
import ToDoEntries from './to_do_entries.jsx';
class ToDoList extends React.Component {
constructor(props) {
super(props);
this.state = { list: [] }
this.add = this.addItem.bind(this);
this.removeItem = this.removeItem.bind(this);
}
addItem(e) { //removed to avoid tl:dr }
render() {
return(
<form onSubmit={this.add}>
<input placeholder='Enter item' type='text' ref={(el) => {this._input = el;} }/>
<button>Add</button>
</form>
<ToDoEntries entries={this.state.list}
removeCallback={this.removeItem}
/>
);
}
}
我的待办事项。jsx
组件:
class ToDoEntries extends React.Component {
constructor(props) {
super(props);
}
renderItems() {
const { entries, removeCallback } = this.props;
function createTasks(item) {
return <li key={item.key}>{item.text}</li>
}
var listItems = entries.map(function(item) {
return(<li onClick={removeCallback} key={item.key}>{item.text}</li>)
})
return listItems;
}
render() {
var todoEntries = this.renderItems();
return(
<ul>
{todoEntries}
</ul>
);
}
}
export default ToDoEntries;
运行此代码将带来:
警告:setState(...):无法在现有状态转换期间更新
问题:
为什么to_do_entries.jsx
的渲染在添加项时立即执行回调,即:
var listItems = entries.map(function(item) {
return(<li onClick={removeCallback(id)} key={item.key}>{item.text}</li>)
})
但是,添加. bind(null, id)
以删除Callback ie。
为什么要输入。jsx的渲染是否立即执行回调?
那么,当您映射到todo的每个
所以现在的代码
<li onClick={removeCallback(id)} </li>
相当于:
var result = removeCallback(id);
<li onClick={result} </li>
您已经正确地指出,使用
bind
将起作用。这是由于这种行为使得它在这些情况下非常有用。
有关更多信息,请参阅mdn文档,但我将在此处引用重要部分:
bind
。。。创建并返回一个新函数,该函数在调用时。。。
在您的情况下,当使用bind并将其赋予
onClick
时,您正在创建一个新函数,该函数将在实际触发click事件时调用,而不是在渲染元素时调用。
查看
removeCallback的另一种方法。绑定(null,id)
是这样的:
var newFunc = () => {
return removeCallback(id);
}
<li onClick={newFunc} </li>
我建议不要这样做,并使用与我为您写的示例相似的方法。呈现绑定到状态的待办事项列表,然后将相关信息传回给父组件以删除该项。在这种情况下,我使用todo的索引来拼接数组,以便将其删除。
当每个todo
但是,这通常被认为是一种不好的做法,因为每次组件运行时,它都会一次又一次地创建此函数。将此值乘以屏幕上的待办事项数量,您将失去性能。这是一个小问题,但我的示例演示了如何解决这个问题。https://codepen.io/w7sang/pen/VWNLJp
// App
class App extends React.Component{
constructor(props) {
super(props);
this.state = { list: [] }
this.add = this.addItem.bind(this);
this.removeItem = this.removeItem.bind(this);
}
addItem(e) {
e.preventDefault();
this.setState({
list: [
...this.state.list,
{
key: Math.random(1,10000),
text: this._input.value
}
]
})
}
removeItem(payload){
this.setState({
list: [
...this.state.list.slice(0, payload.index),
...this.state.list.slice(payload.index + 1)
]
})
}
render() {
return(
<div>
<form onSubmit={this.add}>
<input placeholder='Enter item' type='text' ref={(el) => {this._input = el;} }/>
<button>Add</button>
</form>
<ToDoEntries entries={this.state.list} removeItem={this.removeItem} />
</div>
);
}
}
// TodoEntries [STATELESS]
const ToDoEntries = ({ entries, removeItem } ) => {
return(
<ul>
{ entries.map((item, index) => {
return(<Todo key={item.key} index={index} item={item} removeItem={removeItem} />)
}) }
</ul>
);
}
// Todo
class Todo extends React.Component {
constructor(props){
super(props);
this.state = {};
this.remove = this.remove.bind(this);
}
remove() {
const { index, removeItem } = this.props;
removeItem({
index
});
}
render() {
return <li onClick={this.remove}>{this.props.item.text}</li>
}
}
ReactDOM.render(<App />,document.getElementById('app'));
<div id="app"></div>
问题在于这一部分:
onClick={removeCallback(id)}
我们需要将函数传递给onClick,而不是值。当我们将()
与functionName一起使用时,这意味着您正在调用该方法并将该方法的结果分配给onClick
,如果您在removeCallback中执行设置状态
,则将创建一个无限循环,因为此循环:
render -> removeCallback() -> setState ->
^ |
| |
| |
-----------------------------------------
这就是为什么会出现错误。
检查代码段中abc和abc()的区别:
function abc(){
return 'Hello';
}
console.log('without () = ', abc); //will return the function
console.log('with () = ', abc()); //will return the function result (value)
问题内容: 我正在尝试从渲染视图重构以下代码: 到绑定位于构造函数内的版本。原因是渲染视图中的绑定会给我带来性能问题,尤其是在低端手机上。 我创建了以下代码,但是我不断收到以下错误(很多错误)。该应用似乎陷入了循环: 以下是我使用的代码: 问题答案: 看起来您不小心在render方法中调用了该方法,而您可能想这样做。 如果您不想在onClick处理程序中创建lambda,我认为您将需要两个绑定方法
我正在重写一些旧的ReactJS代码,但在修复此错误时遇到了麻烦(此错误在控制台中重复大约1700次,DOM根本不呈现): 警告:设置状态(…):无法在现有状态转换期间更新(例如在或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到。 我是一个组件,它将它的状态传递给一个应该呈现一些控件的组件。基于单击的控件,状态应该更改,并且应该呈现新的控件。
在进一步的调试中,我发现,以上可能不是根本原因,毕竟,我可以保留通知,但我需要删除我的重定向。
当我试图插入一个新的食谱元素时,我的项目总是崩溃。我使用在能够根据需要更新食谱(例如删除,编辑等)。 如果我将语句切换到,我可以插入元素而没有问题,但是由于删除,我无法删除触发状态更改,并需要状态更改来反映更新而不是道具。有人对这个问题有什么建议吗?谢谢! 配方列表: 配方容器: 配方表:
错误消息: 反应:警告setState无法在现有状态转换期间更新(例如在渲染中) 这是一个react原生应用程序,但我认为,这更多的是一个react问题。 我得到了标题中描述的错误。但我对原因感到困惑,我没有在任何父组件或子组件中设置状态。因此,我有一个孙子组件(CardLayoutResult),它呈现一个listView,每一行呈现一个新组件(Render row),该组件有一个单击事件,单击