单击按钮时为什么我没有从reducer中获取数据?

时间:2017-07-07 22:52:08

标签: javascript reactjs redux

我正在使用React和Redux构建一个简单的应用程序。有四个按钮:向上,向左,向下,向右。如果我点击"向上",它会向上移动项目,当我点击"向下"时,项目会下降,依此类推。但是,当我点击按钮时,项目根本不会移动。更糟糕的是,当我点击它时,我没有在控制台中收到任何错误消息。到目前为止,这是我的代码:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider, connect } from 'react-redux';
import { createStore, combineReducers } from 'redux';
import './index.css';
import registerServiceWorker from './registerServiceWorker';

const reducers = combineReducers({
    vertical: (state={style: 40}, action) => {
        console.log("Inside the vertial reducer", action.type);
        if (action.type === "UP") {
            //Reassign outside the return statement
            state.style = state.style - 10;
            return state;
        } else if (action.type === "DOWN") {
            state.style = state.style + 10;
            return state;
        } else {
            return state;
        }
    },

    horizontal: (state={style: 40}, action) => {
        console.log("Inside the horizontal reducer", action.type);
        if (action.type === "LEFT") {
            state.style = state.style - 10;
            return state;
        } else if (action.type === "RIGHT") {
            state.style = state.style + 10;
            return state;
        } else {
            return state;
        }
    }
});

const a = state => {
    return {
        vertical: state.vertical.style,
        horizontal: state.horizontal.style
    };
};

const b = dispatcher => {
    return {
        clickUp: () => {
            dispatcher({ type: "UP" })
        },
        clickDown: () => {
            dispatcher({ type: "DOWN" })
        },
        clickLeft: () => {
            dispatcher({ type: "LEFT" })
        },
        clickRight: () => {
            dispatcher({ type: "RIGHT" })
        }
    };
};

const container = connect(a, b);

//This is my component
const C = ({ vertical, horizontal, clickUp, clickDown, clickLeft, clickRight }) => {
        console.log("this is from C", vertical);
        return (
            <div>
                <button onClick={clickUp}>Up</button>
                <button onClick={clickDown}>Down</button>
                <button onClick={clickLeft}>Left</button>
                <button onClick={clickRight}>Right</button>
                <img style={{top:vertical+"px", left:horizontal+"px", position:"absolute", width:"40px", height:"40px"}} src={"https://media.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAAglAAAAJDIwYjM0NDEwLTViMTMtNGE2Yi05OGZlLTUwOGE2N2IxMjFlOQ.jpg"} alt="" />
            </div>
        );
};

const App = container(C);

const store = createStore(reducers);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));
registerServiceWorker();

console.log verticalhorizontal缩减器中的类型,并在点击按钮时提供正确的类型。当我尝试console.log我的vertical组件中的C时,单击按钮时没有任何价值。假设在我的控制台中注销一个数字,但事实并非如此。所以,当我点击按钮而没有在控制台中给我任何错误时,似乎我的状态没有被更新。我多次查看我的代码,找不到任何东西。我可以获得有关如何修复代码以及为什么我的代码无声地失败的建议吗?

1 个答案:

答案 0 :(得分:3)

在您的reducer中,您将覆盖以前的状态而不是创建新状态。 Redux不会更新组件状态,因为它认为它仍然与之前相同,因此尝试优化重新渲染过程而不是这样做。

将您的Reducer更新为以下内容,您的应用应该按预期工作:

const reducers = combineReducers({
    vertical: (state={style: 40}, action) => {
        switch (action.type) {
            case 'UP': {
                return Object.assign({}, state, {
                    style: state.style - 10
                });
            }
            case 'DOWN': {
                return Object.assign({}, state, {
                    style: state.style + 10
                });
            }
            default: {
                return state;
            }
        }
    },

    horizontal: (state={style: 40}, action) => {
        switch (action.type) {
            case 'LEFT': {
                return Object.assign({}, state, {
                    style: state.style - 10
                });
            }
            case 'RIGHT': {
                return Object.assign({}, state, {
                    style: state.style + 10
                });
            }
            default: {
                return state;
            }
        }
    }
});