为什么从本地状态更改不会进入全局状态?

时间:2020-04-23 12:51:36

标签: javascript reactjs redux

待办事项

当我尝试编辑自己创建的任务时,我看到了一些修改,但仅限于本地状态。当我查看全局状态的数据时,没有任何变化,数据与创建任务对象后的数据相同。

有趣的是,当EDIT_TASK工作时, action.id = Input中的值,而 action.task =未定义

PS::将所有组件代码放在下面,也许某个地方有错误。

PS:对不起,ENG

组件代码

import React from 'react'
import s from "./../../App.module.css";

class Item extends React.Component {
    state = {
        statusChange: false,
        task: this.props.task
    }

    activeStatusChange = () => {
        this.setState( {
            statusChange: true
           }
       );        
    }

    deActivateStatusChange = () => {
        this.setState( {
            statusChange: false
           }
       );
       this.props.editTask(this.props.task) 
    }

    onStatusChange = (e) => {
        this.setState({
            task: e.target.value
        }) 
    }


    render(){
        return (
            <div className={s.item}>
            <span onClick={this.props.editStatus} className={s.statusTask}>
                {this.props.status  ? <img src="https://img.icons8.com/doodle/48/000000/checkmark.png"/> 
                                    : <img src="https://img.icons8.com/emoji/48/000000/red-circle-emoji.png"/>}
            </span>

            { this.state.statusChange 
                ? <input  onChange={this.onStatusChange} autoFocus={true} onBlur={this.deActivateStatusChange} value={this.state.task} /> 
                : <span  className={this.props.status === true ? s.task : s.taskFalse} onClick={this.activeStatusChange}> {this.state.task} </span>}

            <span onClick={this.props.deleteTask} className={s.close}><img src="https://img.icons8.com/color/48/000000/close-window.png"/></span>

        </div>
        )
    }
}

export default Item;

减速器代码

import React from 'react'
import shortid from 'shortid';

const ADD_TASK = 'ADD_TASK'
const EDIT_TASK = 'EDIT_TASK'

const initialState = {
    tasks: []
};



const mainReducer = (state = initialState, action) => {
    switch (action.type) {

        case ADD_TASK: {
            return {
                ...state,
                tasks: [{
                    id: shortid.generate(),
                    task: action.task,
                    status: false
                }, ...state.tasks]
            }
        }

        case EDIT_TASK: {
            return {
                ...state, 
                tasks: state.tasks.filter((t) => t.id === action.id ? {...t, task: action.newTask} : t)
            }
        }

    default:
        return state
    }
}

//window.store.getState().mainReducer.tasks

export const addTask = task => ({type: 'ADD_TASK', task});
export const editTask = (id,newTask) => ({type: 'EDIT_TASK', id, newTask})


export default mainReducer;

父级组件:

import React from "react";
import s from "./../../App.module.css";
import CurrentTasks from "../current-tasks";
import FilterButtonTasks from "../filter-button-tasks";
import ListTasks from "../tasks-list";

class SetForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: ''
    }
  }

  onInputChange = event => {
    this.setState({
      [event.target.name]: event.target.value
    })
  }

  handleSubmit = event => {
    event.preventDefault();

    if(this.state.text === '') {
      return undefined
    } 
    this.props.addTask(this.state.text)
    this.setState({
      text: ''
    })
  }

  filterTasks = (tasks, activeFilter) => {

    switch (activeFilter) {
      case 'done': {
        return tasks.filter(task => task.status);
      }
      case 'active': {
        return tasks.filter(task => !task.status)
      }
      default:
        return tasks;
    }
  }


  render() {

    const currentTasks = this.filterTasks(this.props.tasks, this.props.filter);

    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <div>
            <input name={"text"} onChange={this.onInputChange} value={this.state.text}placeholder={"Set your task"} className={s.setTask}/>
            <button onClick={this.handleSubmit} className={s.add}>ADD</button>
            <button onClick={this.props.removeAllTasks} className={s.clearAll}>Clear</button>
          </div> 
        </form>
        <CurrentTasks tasks={this.props.tasks}/>
        <ListTasks   currentTasks={currentTasks} editStatus={this.props.editStatus} deleteTask={this.props.deleteTask} editTask={this.props.editTask}/>
        <FilterButtonTasks  currentTasks={currentTasks} changeFilter={this.props.changeFilter} removeAllDone={this.props.removeAllDone}/> 
      </div>
    )
  }
}



export default SetForm;

一个:

import React from 'react'
import Item from './SetItem/item'

const ListTasks = ({currentTasks,editStatus,deleteTask,editTask}) => {
    return (
        currentTasks.map(t => (<Item editStatus={() => editStatus(t.id)}
        deleteTask={() => deleteTask(t.id)}
        key={t.id} task={t.task} status={t.status} editTask={editTask}/>))
    )
}

export default ListTasks;

1 个答案:

答案 0 :(得分:0)

因为,您只在更新本地状态onStatusChange,所以不会在全局状态下更新该状态。因此,在deActivateStatusChange上,您需要以更新后的状态(即this.props.editTask

来调用this.state.task
deActivateStatusChange = () => {
    this.setState({
      statusChange: false
    });
    this.props.editTask(this.state.task); // change is here
  };

问题出在您的EDIT_TASK减速器中:

更改

state.tasks.filter((t) => t.id === action.id ? {...t, task: action.newTask} : t)

收件人

state.tasks.map((t) => t.id === action.id ? {...t, task: action.newTask} : t)

map将更新对象,而不是filter

代码应为:

case EDIT_TASK: {
            return {
                ...state, 
                tasks: state.tasks.map((t) => t.id === action.id ? {...t, task: action.newTask} : t)
            }
        }

似乎您没有将id和newTask传递给editTask操作:

const ListTasks = ({ currentTasks, editStatus, deleteTask, editTask }) => {
  return currentTasks.map(t => (
    <Item
      editStatus={() => editStatus(t.id)}
      deleteTask={() => deleteTask(t.id)}
      key={t.id}
      task={t.task}
      status={t.status}
      editTask={(newTask) => editTask(t.id, newTask)} // change current code to this
    />
  ));

};