React-Redux-在每个状态更改时触发onClick

时间:2018-11-19 21:53:37

标签: javascript reactjs react-redux

我想通过单击TodoItem删除TodoItem,但是React返回“超出了最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。”之所以返回它,是因为在安装时调用了我的on click函数,在输入时输入了keyup或单击了Add按钮之后,而我完全不知道为什么这样工作。

App.js(组件)

class App extends Component {

  render() {
    return (
        <BrowserRouter>
          <div className="App">
            <Header/>
            <div className="container">
                <div className="row">
                    <InputContainer/>
                </div>
                <TodosList todos={this.props.todos}/> {}
            </div>
          </div>
        </BrowserRouter>
    );
  }
}

const mapStateToProps = state => {
    return {
        todos: state.todos
    };
};

const mapDispatchToProps = {};

export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);

TodosList.js(组件)

import * as React from "react";
import { connect } from "react-redux";
import { TodoItem } from "./TodoItem"
import { handleRemoveTodo } from "./actions"

export class TodosListC extends React.Component{

    todoToTodoItem = todo => {
        return <TodoItem key={todo.id} todo={todo} onClick={this.removeTodo(todo.id)}/>
    };

    render(){
        return(
            <ul className='col-sm-6 col-sm-offset-3'>
                {this.props.todos.map(this.todoToTodoItem)}
            </ul>
        )
    }

    removeTodo = e => {
        this.props.handleRemoveTodo(e);
    }

}

const mapStateToProps = state => {
    return {
        todos: state.todos,
        newInput: state.newInput
    };
};

const mapDispatchToProps = { handleRemoveTodo };

export const TodosList = connect(mapStateToProps, mapDispatchToProps)(TodosListC);

Todos.js(还原器)

export const todos = (state = initState, action) => {
  switch (action.type) {
    case 'HANDLE_SAVE_VALUE':
      return [
        ...state,
        {
            id: action.id,
            name: action.text
        }
      ]
    case 'HANDLE_REMOVE_TODO':
      //firing on input keyup, click submit button and component mount
      console.log('HANDLE_REMOVE_TODO',action.id)
      var newState = state.filter(function(todo) {
          return action.id !== todo.id
      });
      return[
        newState
      ]
    default:
      return state
  }
}

const initState = 
    [{id:99998, name: 'Todo99998'},{id:99999, name:'Todo99999'}]

链接到项目zip Link

预先感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您要在此处执行渲染功能

<TodoItem ... onClick={this.removeTodo(todo.id)}/>

onClick需要一个函数,但是您正在removeTodo内调用另一个函数并且什么也不返回,因此,要修复您的代码,您可以将其重新编写为类似的内容

<TodoItem ... onClick={() => this.removeTodo(todo.id)} />

答案 1 :(得分:0)

更新todoToTodoItem方法将解决此错误:

todoToTodoItem = todo => {
  return <TodoItem key = {
    todo.id
  }
  todo = {
    todo
  }
  onClick = {
    () => this.removeTodo(todo.id)
  }
  />
};

答案 2 :(得分:0)

我已经整理了一下代码,有一个mapToProps配置错误和不需要的方法,我已经删除了那些会在单击时删除元素的东西,但是您需要修复reducer中的一些东西才能删除特定数据。祝你好运

////TodoListC.js

import * as React from "react";
import {
  connect
} from "react-redux";
import {
  bindActionCreators
} from "redux";
import {
  TodoItem
} from "./TodoItem"
import {
  handleRemoveTodo
} from "./actions"

export class TodosListC extends React.Component {


    render() {
        return ( <
          ul className = 'col-sm-6 col-sm-offset-3' > {
            this.props.todos.map((todo) => < TodoItem key = {
                todo.id
              }
              id = {
                todo.id
              }
              todo = {
                todo
              }
              handleRemoveTodo = {
                this.props.handleRemoveTodo
              }
              />)} <
              /ul>
            )
          }


        }

        const mapStateToProps = state => {
          return {
            todos: state.todos,
            newInput: state.newInput
          };
        };

        const mapDispatchToProps = dispatch => bindActionCreators({
          handleRemoveTodo
        }, dispatch)

        export const TodosList = connect(mapStateToProps, mapDispatchToProps)(TodosListC);

////TodoItem.js
import * as React from "react";

export const TodoItem = ({ todo, id, handleRemoveTodo}) => {

	return(
		<li key={id} onClick={() => handleRemoveTodo(id)}>{todo.name}</li>
	)

};