@vantsymbalenko

Почему не обновляются props после dispatch?

После dispatch в store не обновляется компонент. Тоесть через DevToolsExtension можна увидеть что store обновился, но компонент не принмает новых props.

action.js
export default function add(time, task, id){
	if(!task || !time){
		return {
			type: "SET_ERROR",
			text: "Error, invalid data"
		}
	}
	return{
		type: "ADD_TASK",
		id: id,
		time: time,
		task: task
	}
}


reducer.js

let minute = [1,2,4];
let initialState = {
	add: false,
	tasks : [
		{id: 1, time: new Date().toString(), task : 'Some text 1'},
		{id: 2, time: new Date().toString(), task : 'Some text 2'},
		{id: 3, time: new Date().toString(), task : 'Some text 3'}
	]	
};
export default function addDelete(state = initialState, action){
	switch (action.type) {
		case "ADD_TASK":{
			const newState ={...state};
			newState.tasks.push({id: action.id, time : action.time, task: action.task});
			return newState;
		}
		case "DELETE_TASK" :{ 
			let newState = {...state};
			newState.tasks.splice(action.id - 1, 1);
			return newState;
		}
		case "SET_ACSSES" : {
			return {
				...state,
				add: !state.add
			}
		}
		default:
			return state;
	}
}


ну и сам компонент
import React, {Component} from 'react';
import {connect} from 'react-redux';
import addTask from '../actions/addTask';
import ComponentAddForm from '../components/AddForm';

class AddForm extends Component{
	render(){
		return(
			<ComponentAddForm error = {this.props.errors} add = {this.props.add} id={this.props.id + 1}/>	
		);
	}
}
const mapStateToProps = (state) => ({
	errors: state.errors.text,
	id: state.addDelete.tasks[state.addDelete.tasks.length-1].id
});
const mapDispatchToProps = {
	add : addTask
};

export default connect(mapStateToProps, mapDispatchToProps)(AddForm);
  • Вопрос задан
  • 1036 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Вы мутируете массив tasks который передаете в компонент. При получении новых свойств, после обновления стора, в компоненте в который вы предаете его происходит проверка:
this.props.tasks === nextProps.tasks; // true
Она возвращает true, так как это тот же самый массив и компонент не обновляется.

Исправьте так:
export default function addDelete(state = initialState, action){
  switch (action.type) {
    case "ADD_TASK":
      return {
        ...state,
        tasks: [...state.tasks, {{id: action.id, time : action.time, task: action.task}}],
      };
    case "DELETE_TASK":
      return {
        ...state,
        tasks: [...state.tasks.filter(task => task.id != action.id)],
      };
    case "SET_ACSSES":
      return {
        ...state,
        add: !state.add,
      };
    default:
      return state;
  }
}


Но будет еще лучше, если поправите свои actionCreators. Кладите полезную нагрузку в ключ payload:
export default function add(time, task, id){
  if(!task || !time){
    return {
      type: "SET_ERROR",
      payload: "Error, invalid data"
    };
  }

  return{
    type: "ADD_TASK",
    payload: {
      id: id,
      time: time,
      task: task,
    },
  }
}


export const deleteTask = id => ({
  type: 'DELETE_TASK',
  payload: id,
});


Тогда код редьюсера будет такой:
export default function addDelete(state = initialState, action) {
  const { type, payload } = action;

  switch (type) {
    case "ADD_TASK":
      return {
        ...state,
        tasks: [...state.tasks, payload],
      };
    case "DELETE_TASK":
      return {
        ...state,
        tasks: [...state.tasks.filter(task => task.id != payload)],
      };
    case "SET_ACSSES":
      return {
        ...state,
        add: !state.add,
      };
    default:
      return state;
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы