应用实例
现在我们来应用上面实现的createStore
,我们定义一个counter,显示state,具有加减按钮,用来触发increment action和decrement action. 现在我们来一步步实现它.
第一步
定义一个Purely Presentational Component,这种组件负责渲染出view,而不在意行为和数据。 我们将其命名为Counter,接收三个参数,第一个是value
,用来显示counter的结果,我们的state里唯一的数据也将是这个对应的value,第二个第三个参数是behavior function, 分别是increment
和 decrement
,还记得吗,在应用redux体系的app里,dispatch是我们唯一能够改变state的方法,所以这两个函数里必定包裹着dispatch,以便于我们对state进行更改。
const Counter = ({value, onIncrement, onDecrement}) => (
<div>
<h1>{value}</h1>
<button onClick={onIncrement}>+</button>
<button onClick={onIncrement}>-</button>
</div>
)
第二步
定义一个reducer,让其根据action的不同来决定state变化的行为.
// 我们默认state初始状态为0
const counterReducer = (state=0, action => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
if(state -1 < 0 ) return 0
return state -1
default:
return state
}
}
第三步
通过前面实现的createStore
,传入counterReducer
,创建一个store.
const store = createStore(counterReducer)
store.getState() // 0
第三步
定义一个render方法,用来将组件render到dom中,其中将应用上面的创建的组件,并传入参数.
const render = () => {
ReactDom.render(
<Counter
value={store.getState()}
onIncrement={() =>
store.dispatch({
type: 'INCREMENT'
})
}
onDecrement={() =>
store.dispatch({
type: 'DECREMENT'
})
}
/>,
document.getElementById('root')
)
}
第四步
将render订阅到store上,一旦state发生改变,就会触发render函数,更新浏览器上的渲染结果.
store.subscribe(render)
// For rendering initial state, we manually call it.
render()
效果
订阅更多的函数来看看效果?
const unsubscribeShowState = store.subscribe(() =>
{
console.log(`state更新了!state是${store.getState()}`)
}
)
我们完整实现了一个counter,并且这完完全全是靠我们自己实现的store来控制state和view的更新逻辑,使用过redux但是没有具体思考过内部实现原理的同学们,应该会有更清晰的认知。