Redux Component不会在商店更改时更新

时间:2017-02-19 19:16:19

标签: javascript reactjs redux

我正在尝试使用Redux + React - 我已经用connect()为一个小的todo应用程序连接了Redux的相关位,但我不能在我的生活中让组件更新和显示反映的商店更改。存储状态确实更新但组件不会更新。以下是我的代码中的相关位:

actionTypes.js

export const ADD_TODO = "ADD_TODO";
export const DELETE_TODO = "DELETE_TODO";
export const CLEAR_TODO = "CLEAR_TODO";
export const COMPLETE_TODO = "COMPLETE_TODO";

reducers.js

import {ADD_TODO, COMPLETE_TODO, DELETE_TODO, CLEAR_TODO} from '../actions/actionTypes';
const todoApp = (state, action) => {
    let updatedState;
    switch (action.type) {
        case ADD_TODO:
            updatedState = Object.assign({}, state);
            updatedState.todo.items.push({
                text: action.text,
                completed: false
            });
            return updatedState;
        case COMPLETE_TODO:
            updatedState = Object.assign({}, state);
            updatedState.todo.items[action.index].completed = true;
            return updatedState;
        case DELETE_TODO:
            const items = [].concat(state.todo.items);
            items.splice(action.index, 1);
            return Object.assign({}, state, {
                todo: {
                    items: items
                }
            });
        case CLEAR_TODO:
            return Object.assign({}, state, {
                todo: {
                    items: []
                }
            });
        default:
            return state;
    }
};

export default todoApp;

actions.js

import {ADD_TODO, COMPLETE_TODO, DELETE_TODO, CLEAR_TODO} from './actionTypes.js';
export const addTodoCreator = (text) => {
    return {
        type: ADD_TODO,
        text: text,
        completed: false
    }
};

export const completeTodo = (index) => {
    return {
        type: COMPLETE_TODO,
        index: index
    }
};

export const deleteTodo = (index) => {
    return {
        type: DELETE_TODO,
        index: index
    }
};

export const clearTodo = (index) => {
    return {
        type: CLEAR_TODO,
        index: index
    }
};

AddTodoContainer.js

import { connect } from 'react-redux';
import TodoList from '../components/TodoList';
const mapStateToProps = (state, ownProps) => {
    return {
        todo: state.todo
    }

};

export default connect(mapStateToProps)(TodoList);

TodoListContainer.js

import { connect } from 'react-redux';
import {addTodoCreator} from '../actions/actions';
import AddTodo from '../components/AddTodo';
const mapStateToProps = (state) => {
    console.log(state);
    return {
        todo: state.todo
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        addTodo: (text) => {
            const action = addTodoCreator(text);
            dispatch(action);
        },
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(AddTodo);

AddTodo.js

import React from 'react'
const handler = (addTodo) => {
    const text = document.getElementById('textInput').value;
    addTodo(text);
};

const AddTodo = ({addTodo}) => {
    return (
        <div>
            <input id="textInput" type="text" className="textInput" />
            <button onClick={(handler).bind(null, addTodo)}>Add</button>
        </div>
    )
}

export default AddTodo

TodoList.js

import React from 'react';
import AddTodoContainer from '../containers/AddTodoContainer';

class TodoList extends React.Component {
    render () {
        console.log(this.props);
        return (
            <div>
                <ul>
                    {this.props.todo.items.map((item) => {
                        return <li>
                            {item.text}
                        </li>
                    })}
                </ul>
                <AddTodoContainer/>
            </div>
        )
    }
}

export default TodoList;

我已经尝试了Troubleshooting下的所有建议,据我所知,我并没有改变状态。减速器正在点火,我可以注销状态。代码存储在react-fulltodo http://gogs.dev.dylanscott.me/dylanrhysscott/learn-redux

由于

迪伦

1 个答案:

答案 0 :(得分:0)

您正在将todo传递给您的组件,而todo对象更新后,redux状态下的实际todo对象与之前的对象完全相同。因此,反应看不到对象的变化。例如:

const a = { foo: 'bar' };
const b = a;

b.foo = 'I made a change';
console.log(a==b); 
// logs true because a and b are the same object
// This is exactly what's happening in React.
// It sees the object as the same, so it does not update.

您需要克隆todo对象,以便反应将其视为已更改/新对象。

在你的减速机中:

switch (action.type) {
    case ADD_TODO:
        updatedState = Object.assign({}, state);
        // Shallow clone updatedState.todo
        updatedState.todo = Object.assign({}, updatedState.todo);
        updatedState.todo.items.push({
            text: action.text,
            completed: false
        });
        return updatedState;

与此同时,如果您将state.todo.items传递给您的组件,则无需克隆todo,但您必须克隆items。因此,将来如果您有一个直接mapStateToPropsstate.todo.items的组件,它将会遇到同样的问题,因为您没有像ADD_TODO中那样克隆项数组,就像您在{ {1}} reducer。