首页 > 解决方案 > 在 Redux Reactjs 中对切换 checkall 按钮做出反应

问题描述

目前我正在学习 Redux,我现在遇到的问题是 selectall 复选框应该在有人点击这个按钮时工作。结果是所有复选框都应该切换(选中或取消选中)。但现在我被我的逻辑困住了。当有人调用 selectAll 函数时,它应该遍历所有输入复选框,并且从那时起它应该选中或取消选中所有复选框。

import React from 'react';
import { selectAll } from '../actions';
import { connect } from 'react-redux';

const CheckAll = () => {
    return (
        <div>
            TodoList <input type="checkbox" onChange={e => {
                e.preventDefault();
                selectAll()
                }}/>
        </div>
    )
}

const mapDispatchToProps = dispatch => {
    return {
        selectAll: () => dispatch({type: 'SELECT_ALL'})
    }
}

export default connect(mapDispatchToProps)(CheckAll);

import React from 'react';
import { connect } from 'react-redux';
import { removeTodo } from '../actions';

const TodoList = ({ todos, removeTodo }) => {
    return (
        <div>
             {todos.map((todo) => {
                return (
                    <li key={todo.id}>
                        // checkbox should be toggling here when somene clicks on the selectAll checkbox. 
                        <input type="checkbox" checkbox="false"/> 
                        {todo.text}
                        <span onClick={e => removeTodo(todo.id, 1)}>x</span>
                    </li>
                )
            } )}
         
        </div>
    )
}

const mapDispatchProps = dispatch => {
    return {
        removeTodo: id => dispatch(removeTodo(id))
    }
}

const mapStateToProps = state => {
    return {
        todos: state.reducer || []
    }
}

export default connect(mapStateToProps, mapDispatchProps)(TodoList);

// the reducer below

const reducer = (state = [], action) => {
    switch(action.type) {
        case 'ADD_TODO':
            return [
                ...state, 
                {
                    id: action.id,
                    text: action.payload,
                    completed: action.completed
                }
            ];
        case 'REMOVE_TODO':
            return state.filter(({id}) => id !== action.id);
        case 'SELECT_ALL':
            console.log('');
            const allMarked = state.every(action => action.completed);
           
            return state.map(todo => ({
                ...todo,
                completed: !allMarked
            }));
        default: 
            return state;
    }
}

export default reducer;

我想要一个功能复选框,当每个人都单击该复选框时,它应该切换选中或未选中。但请记住,如果用户单击单个复选框,它不应影响选中/取消选中按钮。

标签: reactjsredux

解决方案


主要问题是您的复选框不是受控输入。您正在查看该completed属性以查看是否已选中这些框,但它们的值未链接到该属性,并且在它们更改时不会更新状态。您需要将该值作为其checked属性提供给输入,并添加一个onChange处理程序以使其保持最新:

             {todos.map((todo, index) => {
                return (
                    <li key={todo.id}>
                        // checkbox should be toggling here when somene clicks on the selectAll checkbox. 
                        <input type="checkbox" checked={todo.completed} onChange={() => checkTodo(index)}/> 
                        {todo.text}
                        <span onClick={e => removeTodo(todo.id, 1)}>x</span>
                    </li>
                )
            } )}

对于处理程序,您需要添加一个新的操作和减速器案例:

case 'CHECK_TODO':
            const copy = Array.from(state);
            copy[action.index].completed = !copy[action.index].completed;
            return copy;
            break;

您当然需要将索引添加到操作中,或者如果您愿意,可以使用 ID,并映射其调度。同样正如Junius指出的那样,请确保您正确引用了您的道具,但我认为您不需要this功能组件,也许我以前从未见过它,但我认为 JSX 组件不会呈现不带括号:

const CheckAll = (props) => {
  return (
    <div>
      <TodoList/> <input type="checkbox" onChange={e => {
            e.preventDefault();
            props.selectAll()
      }}/>
   </div>
  )
}

推荐阅读