removeTodo 操作不从状态中删除
removeTodo action not removing from state
我不确定这里哪里出错了,但是当我触发我的 removeTodo 操作时,没有任何反应。我相信这是我的传递错误,但我不太明白。我认为通过将我的操作设置为接受一个待办事项作为其有效负载,然后在我的调度中我为该操作提供一个 todo.id,它可以删除所述 id。不太明白为什么这行不通。
TodoItem.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { removeTodo } from '../actions';
import '../../css/Todo.css';
const mapDispatchToProps = dispatch => {
return {
removeTodo: todo => dispatch(removeTodo(todo.id))
};
};
const mapStateToProps = state => {
return {todos: [...state.todos]};
};
class ConnectedTodoItem extends Component {
render() {
const {handleToggle, todoId} = this.props;
const mappedTodos = this.props.todos.map((todo, index) => (
<div className='todo-item'>
<span onClick={handleToggle} index={index} id={todoId}>
{todo.title}
</span>
<button type='submit' className='rem-btn' id={todoId} onClick={this.props.removeTodo}>X</button>
</div>
));
return (
mappedTodos
);
}
}
const TodoItem = connect(mapStateToProps, mapDispatchToProps) (ConnectedTodoItem);
export default TodoItem;
reducers.js
import { ADD_TODO } from '../constants/action-types';
import { REMOVE_TODO } from '../constants/action-types';
import uuidv1 from 'uuid';
const initialState = {
todos: []
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return {
...state,
todos: [...state.todos,
{
title: action.payload.inputValue,
id: uuidv1()
}]
}
case REMOVE_TODO:
return {
...state,
todos: [...state.todos.filter(todo => todo.id !== action.payload)]
}
default:
return state;
}
}
export default rootReducer;
actions.js
import { ADD_TODO } from '../constants/action-types';
import { REMOVE_TODO } from '../constants/action-types';
export const addTodo = (todo) => (
{
type: ADD_TODO,
payload: todo
}
);
export const removeTodo = (todo) => (
{
type: REMOVE_TODO,
payload: todo.id
}
)
乍一看,问题似乎出在您的调用方式上 removeTodo
如您所见,该函数接受一个 todo
参数,然后从中提取 ID。
const mapDispatchToProps = dispatch => {
return {
removeTodo: todo => dispatch(removeTodo(todo.id))
};
};
但是你没有在此处传递待办事项。
onClick={this.props.removeTodo}
试试这个:
onClick={() => this.props.removeTodo(todo)}
更新,继续威廉的思路。我会执行以下操作,专门传递 id
而不是整个对象。这会让您更容易理解您要更新的内容。
1) 调度函数
const mapDispatchToProps = dispatch => {
return {
removeTodo: id => dispatch(removeTodo(id))
};
};
2)调用函数
onClick={() => this.props.removeTodo(todoId)}
3) 动作
export const removeTodo = (id) => (
{
type: REMOVE_TODO,
id
}
)
4) 减速器
case REMOVE_TODO: {
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.id)
}
}
为了补充 Andy 的回答,您似乎也在调度调用中提取了 id,但您已经在定义 removeTodo 的 actions.js 中这样做了,所以除非您在其中有嵌套的 id todo.id,您需要将其从任一位置删除。
我不确定这里哪里出错了,但是当我触发我的 removeTodo 操作时,没有任何反应。我相信这是我的传递错误,但我不太明白。我认为通过将我的操作设置为接受一个待办事项作为其有效负载,然后在我的调度中我为该操作提供一个 todo.id,它可以删除所述 id。不太明白为什么这行不通。
TodoItem.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { removeTodo } from '../actions';
import '../../css/Todo.css';
const mapDispatchToProps = dispatch => {
return {
removeTodo: todo => dispatch(removeTodo(todo.id))
};
};
const mapStateToProps = state => {
return {todos: [...state.todos]};
};
class ConnectedTodoItem extends Component {
render() {
const {handleToggle, todoId} = this.props;
const mappedTodos = this.props.todos.map((todo, index) => (
<div className='todo-item'>
<span onClick={handleToggle} index={index} id={todoId}>
{todo.title}
</span>
<button type='submit' className='rem-btn' id={todoId} onClick={this.props.removeTodo}>X</button>
</div>
));
return (
mappedTodos
);
}
}
const TodoItem = connect(mapStateToProps, mapDispatchToProps) (ConnectedTodoItem);
export default TodoItem;
reducers.js
import { ADD_TODO } from '../constants/action-types';
import { REMOVE_TODO } from '../constants/action-types';
import uuidv1 from 'uuid';
const initialState = {
todos: []
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return {
...state,
todos: [...state.todos,
{
title: action.payload.inputValue,
id: uuidv1()
}]
}
case REMOVE_TODO:
return {
...state,
todos: [...state.todos.filter(todo => todo.id !== action.payload)]
}
default:
return state;
}
}
export default rootReducer;
actions.js
import { ADD_TODO } from '../constants/action-types';
import { REMOVE_TODO } from '../constants/action-types';
export const addTodo = (todo) => (
{
type: ADD_TODO,
payload: todo
}
);
export const removeTodo = (todo) => (
{
type: REMOVE_TODO,
payload: todo.id
}
)
乍一看,问题似乎出在您的调用方式上 removeTodo
如您所见,该函数接受一个 todo
参数,然后从中提取 ID。
const mapDispatchToProps = dispatch => {
return {
removeTodo: todo => dispatch(removeTodo(todo.id))
};
};
但是你没有在此处传递待办事项。
onClick={this.props.removeTodo}
试试这个:
onClick={() => this.props.removeTodo(todo)}
更新,继续威廉的思路。我会执行以下操作,专门传递 id
而不是整个对象。这会让您更容易理解您要更新的内容。
1) 调度函数
const mapDispatchToProps = dispatch => {
return {
removeTodo: id => dispatch(removeTodo(id))
};
};
2)调用函数
onClick={() => this.props.removeTodo(todoId)}
3) 动作
export const removeTodo = (id) => (
{
type: REMOVE_TODO,
id
}
)
4) 减速器
case REMOVE_TODO: {
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.id)
}
}
为了补充 Andy 的回答,您似乎也在调度调用中提取了 id,但您已经在定义 removeTodo 的 actions.js 中这样做了,所以除非您在其中有嵌套的 id todo.id,您需要将其从任一位置删除。