我对React有问题。
当我按下“ +”按钮时,此控制台消息出现,但没有任何反应:

Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`


我发现了几个标题相似的问题,但它们之间的共同点是在render方法中调用了setState函数。

我的渲染方法没有调用,但是出现错误。

为什么?

感谢您的阅读。

码:

import React from 'react';

const TodoForm = ({addTodo}) => {
    let input;

    return (
        <div>
            <input
                ref={node => {
                    input = node;
                }}

            />
            <button onClick={() => {
                addTodo(input.value);
                input.value = '';
            }}>
                +
            </button>
        </div>
    );
};


const Todo = ({todo, remove}) => {
    // Each Todo
    return (<li onClick={remove(todo.id)}>{todo.text}</li>)
};

const TodoList = ({todos, remove}) => {
    // Map through the todos
    const todoNode = todos.map((todo) => {
        return (<Todo todo={todo} key={todo.id} remove={remove}/>)
    });
    return (<ul>{todoNode}</ul>);
};

const Title = () => {
    return (
        <div>
            <div>
                <h1>to-do</h1>
            </div>
        </div>
    );
};

window.id = 0;
class TodoApp extends React.Component {
    constructor(props) {
        // Pass props to parent class
        super(props);
        // Set initial state
        this.state = {
            data: []
        }
    }

    // Add todo handler
    addTodo(val) {
        // Assemble data
        const todo = {text: val, id: window.id++}
        // Update data
        this.state.data.push(todo);
        // Update state
        console.log('setting state...');
        this.setState({data: this.state.data});
    }

    // Handle remove
    handleRemove(id) {
        // Filter all todos except the one to be removed
        const remainder = this.state.data.filter((todo) => {
            if (todo.id !== id) return todo;
        });
        // Update state with filter
        this.setState({data: remainder});
    }

    render() {
        // Render JSX
        return (
            <div>
                <Title />
                <TodoForm addTodo={
                    (val)=>{

                        this.addTodo(val)
                    }
                }/>
                <TodoList
                    todos={this.state.data}
                    remove={this.handleRemove.bind(this)}
                />
            </div>
        );
    }
}
export default TodoApp;

最佳答案

Todo的渲染方法中,调用remove,这是错误状态更新发生的地方。

要解决此问题,请从handleRemoveTodoApp方法返回一个更新状态的函数。简化版:

handleRemove(id) {
  return () => {
    ...
    this.setState({ data: remainder });
  }
}


在这里也要注意,因为您正在使用当前状态,所以最好使用setState回调(将prevState作为参数),而不要依赖this.state

setState docs

关于javascript - react :在现有状态转换期间无法更新,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44292866/

10-12 12:35
查看更多