Почему изменения из местного состояния не go в глобальное состояние? - PullRequest
4 голосов
/ 23 апреля 2020

Список дел

При попытке отредактировать созданное задание я вижу некоторые изменения, но только в локальном состоянии. Когда я смотрю на данные глобального состояния, ничего не меняется, данные остаются такими же, как и после создания объекта задач.

Интересно также отметить, что когда сработал случай EDIT_TASK, действие. id = значения из Input и action.task = undefined

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 голосов
/ 23 апреля 2020

Поскольку вы обновляете только локальное состояние 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)

To

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

};

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...