应用实例

现在我们来应用上面实现的createStore,我们定义一个counter,显示state,具有加减按钮,用来触发increment action和decrement action. 现在我们来一步步实现它.

第一步

定义一个Purely Presentational Component,这种组件负责渲染出view,而不在意行为和数据。 我们将其命名为Counter,接收三个参数,第一个是value,用来显示counter的结果,我们的state里唯一的数据也将是这个对应的value,第二个第三个参数是behavior function, 分别是incrementdecrement ,还记得吗,在应用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()

效果

JSBin

订阅更多的函数来看看效果?
const unsubscribeShowState = store.subscribe(() => 
  {
    console.log(`state更新了!state是${store.getState()}`)
  }
)

我们完整实现了一个counter,并且这完完全全是靠我们自己实现的store来控制state和view的更新逻辑,使用过redux但是没有具体思考过内部实现原理的同学们,应该会有更清晰的认知。


github commit

results matching ""

    No results matching ""