我正在尝试使用简单的 Redux 实现一个计数器组件,使用 createStore
创建了 store
并使用了 store.dispatch
完整代码:
/*==================================================
This is only to format the code, I have used this editor,
you can scroll down for the fiddle having error.
==================================================*/
const createStore = Redux.createStore;
const counter = (state = {
counter: 0
}, action) => {
console.log('counter', state)
switch (action.type) {
case 'INCREMENT':
return state.counter + 1;
case 'DECREMENT':
return state.counter - 1;
default:
return state;
}
}
const store = createStore(counter);
let Counter = React.createClass({
getInitialState() {
return store.getState()
},
incrementCounter() {
store.dispatch({
type: 'INCREMENT'
});
},
decrementCounter() {
store.dispatch({
type: 'DECREMENT'
});
},
render() {
console.log('NEW STATE:', store.getState(), this.state)
return (
<div>
<p>{this.state.counter}</p>
<div>
<button onClick={this.incrementCounter}>+</button>
<button onClick={this.decrementCounter}>-</button>
</div>
</div>
)
}
})
ReactDOM.render( < Counter / > , document.getElementById('container'))
我的问题:当我点击 incrementCounter
和 decrementCounter
函数
最佳答案
你有几个问题
- 您需要订阅状态更改,这很重要,因为您的组件不知道新状态
-
state
是Object
, 你必须从counter
返回Object
,在您的示例中,您返回Number
在INCREMENT
和DECREMENT
const createStore = Redux.createStore;
const counter = (state = {
counter: 0
}, action) => {
switch (action.type) {
case 'INCREMENT':
return Object.assign({}, state, { counter: state.counter + 1 });
case 'DECREMENT':
return Object.assign({}, state, { counter: state.counter - 1 });
default:
return state;
}
}
const store = createStore(counter);
let Counter = React.createClass({
incrementCounter() {
store.dispatch({ type: 'INCREMENT' });
},
decrementCounter() {
store.dispatch({ type: 'DECREMENT' });
},
render() {
return <div>
<p>{ this.props.value }</p>
<div>
<button onClick={this.incrementCounter}>+</button>
<button onClick={this.decrementCounter}>-</button>
</div>
</div>
}
})
const render = () => {
ReactDOM.render(
// get updated state value, and pass it to component
<Counter value={ store.getState().counter } />,
document.getElementById('container')
)
};
store.subscribe(render);
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
注意:对于React
, Redux
( react-redux
) 提供名为 Provider
的组件, 你不需要使用 store.subscribe
,但是在后台逻辑类似于我的示例
更新:
const { Provider, connect } = ReactRedux;
const { createStore, bindActionCreators } = Redux;
// Component
let Counter = ({ value, onIncrement, onDecrement }) => (
<div>
<p>{ value }</p>
<div>
<button onClick={ onIncrement }>+</button>
<button onClick={ onDecrement }>-</button>
</div>
</div>
);
// Reducer
const counter = (state = {
counter: 0
}, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, counter: state.counter + 1 };
case 'DECREMENT':
return { ...state, counter: state.counter - 1 };
default:
return state;
}
}
// actions
const onIncrement = () => {
return { type: 'INCREMENT' }
}
const onDecrement = () => {
return { type: 'DECREMENT' }
};
// map state and actions
const mapStateToProps = (state) => {
return {
value: state.counter
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(
{ onIncrement, onDecrement },
dispatch
);
}
Counter = connect(
mapStateToProps,
mapDispatchToProps
)(Counter);
const store = createStore(counter);
ReactDOM.render(
<Provider store={ store }>
<Counter />
</Provider>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.6/react-redux.js"></script>
<div id="container"></div>
关于javascript - 简单的 Redux 计数器组件实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40768308/