简单终极版Counter组件实现
问题描述:
我想实现用简单的终极版计数器组成部分,创造了store
使用createStore
和使用store.dispatch
简单终极版Counter组件实现
完整代码:
/*==================================================
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>
\t <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>
答
你的主要问题是:
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;
}
}
尤其是这行:
case 'INCREMENT':
return state.counter + 1;
case 'DECREMENT':
return state.counter - 1;
什么要退?一个号码!但是,你的状态形状的物体{counter: Number}
所以,你必须返回一个新的对象是这样的:
case 'INCREMENT':
return {counter: state.counter + 1}
case 'DECREMENT':
return {counter: state.counter - 1}
上述变化应该修复它。 是你的减速机内更灵活,您应该分配新的对象,像这样的存在状态:
case 'INCREMENT':
return {
...state,
counter: state.counter + 1
}
case 'DECREMENT':
return {
...state,
counter: state.counter - 1
}
作为亚历山大已经在这里做,你也减速需要使用Object.assign因为它是返回一个整数(新计数)而不是定义为初始状态的状态对象,例如{counter:1}。 –
@ alexander-t,感谢您的帮助。我真的很感激你是否也可以给我一个'Provider'的例子。请........ –
@RAVI MONE看看我的更新... –