React-Redux - включение OnClick при каждом изменении состояния - PullRequest
0 голосов
/ 20 ноября 2018

Я хочу удалить TodoItem, нажав на TodoItem, но React возвращает «Превышена максимальная глубина обновления. Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы.». Он возвращается, потому что моя функция при нажатии вызывается при монтировании, keyup при вводе или после нажатия кнопки Добавить, и я совершенно не знаю, почему она работает таким образом.

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 Ссылка

Заранее спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Вы выполняете функцию визуализации здесь

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

onClick ожидает функцию, но вы вызываете другую функцию внутри removeTodo и ничего не возвращаете, поэтому, чтобы исправить свой код, вы можете просто переписать его как-то так:

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

0 голосов
/ 20 ноября 2018

Я немного очистил код, произошла неправильная конфигурация mapToProps и нежелательных методов, я удалил те, которые будут удалять элемент по щелчку, но вам нужно исправить некоторые вещи в редукторе, чтобы удалить определенные данные. Желаем удачи

////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>
	)

};
0 голосов
/ 20 ноября 2018

Обновите метод todoToTodoItem, чтобы исправить эту ошибку:

todoToTodoItem = todo => {
  return <TodoItem key = {
    todo.id
  }
  todo = {
    todo
  }
  onClick = {
    () => this.removeTodo(todo.id)
  }
  />
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...