React-redux状态是更新,但我不影响视图

时间:2018-03-23 15:29:18

标签: javascript reactjs redux

我正在尝试制作一个todo应用程序来学习React Redux。 我的状态是这样的

[
  {
    taskName:"ABS",
    status: true
  },
  {
    taskName:"XYZ",
    status: false
  }
]

基本上,每个任务都是一个对象。我想在每次按下按钮时切换特定任务的状态(它在红色和绿色之间改变颜色),所以我设计我的减速器如下:

尝试1:

var stateClone = [...state];
stateClone[action.index].status = !stateClone[action.index].status;
return stateClone;

尝试2:

var cloneTask = {...state[action.index]}
cloneTask.status = !cloneTask.status;
state[action.index] = cloneTask
localStorage.setItem('tasks', JSON.stringify(state));
return [...state];

据我了解,两者都是纯粹的功能。两者都返回正确的状态,但只有尝试2成功更新了视图,尝试1确实更新了状态,但没有正确更新视图。

有人帮助我。谢谢!

**

import React, { Component } from 'react';
import TaskItem from './TaskItem';
import { connect } from 'react-redux'
class TaskList extends Component {
    constructor(props){
        super(props);
        this.state = {
            filterName: '',
            filterStatus: -1
        };
    }
    onChange = (event)=>{
        var target = event.target;
        var name = target.name;
        var value = target.value;
        console.log(name)
        this.props.onFilter(name==='filterName'?value:this.state.filterName, 
                            name==='filterStatus'?value:this.state.filterStatus);
        this.setState({
            [name]:value
        });
    }
    render() {
        // console.log(this.props);
        var { tasks } = this.props;
        var { filterName, filterStatus } = this.state;
        var elemTask = tasks.map((item, index)=>{
            return <TaskItem 
                        key={index+1} 
                        item={item} 
                        index={index} 
                        deleteTask={this.props.deleteTask}
                        editTask = {this.props.editTask}
                    />
        }); 
        return (
            <table className="table table-bordered table-hover mt-15">
                <thead>
                    <tr>
                        <th className="text-center">STT</th>
                        <th className="text-center">Task</th>
                        <th className="text-center">Status</th>
                        <th className="text-center">Action</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td></td>
                        <td>
                            <input 
                                type="text"
                                className="form-control"
                                name="filterName"
                                value={filterName}
                                onChange={this.onChange}
                            />
                        </td>
                        <td>
                            <select name="filterStatus" 
                                    value={filterStatus} 
                                    className="form-control"
                                    onChange={this.onChange}>
                                <option value={-1}>All</option>
                                <option value={0}>OnHold</option>
                                <option value={1}>Active</option>
                            </select>
                        </td>
                        <td></td>
                    </tr>
                    {elemTask}
                    
                </tbody>
            </table>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        tasks: state.tasks
    };
}
export default connect(mapStateToProps, null)(TaskList);

**

我应该从商店获取状态的反应文件

import * as types from '../constants/ActionTypes';

var data = JSON.parse(localStorage.getItem('tasks'));
var initialState = data? data: [];

var myReducer = (state=initialState, action) => {
	switch(action.type){
		case types.LIST_ALL:
			return state;

		case types.ADD_TASK:
			var newTask = {
				id: Math.random(),
				name: action.task.name	,
				status: action.task.status==='true'
			}
			state.push(newTask);
			localStorage.setItem('tasks', JSON.stringify(state));
			return [...state];

		case types.UPDATE_STATUS:
			// var stateClone = [...state];
			// stateClone[action.index].status = !stateClone[action.index].status;
			// console.log(stateClone);
			// return stateClone;
			
			var cloneTask = {...state[action.index]}
			cloneTask.status = !cloneTask.status;
			state[action.index] = cloneTask
			localStorage.setItem('tasks', JSON.stringify(state));
			console.log(state);
			return [...state];
		default: return state
	}
};

export default myReducer; 

1 个答案:

答案 0 :(得分:3)

在这两种情况下,你改变状态。

首先,复制对象,然后更改其中一个; React看到相同的对象,并认为没有任何改变。

在第二个中,您创建一个新对象,但将其放在现有数组中。 React看到的阵列仍然相同,并认为没有任何变化。

您需要返回一个新数组,并为已更改的数组添加新对象。

这样做的一种方法是基本上结合你的两次尝试:

var stateClone = [...state];
var cloneTask = {...state[action.index]};
cloneTask.status = !cloneTask.status;
stateClone[action.index] = cloneTask;
return stateClone;

应该工作。