React模块化约定 - DuckComponent
saga-duck将Redux层面进行了模块化,而React也可以进行同步的模块化,与duck一一对应。
我们约定传递 { duck, store, dispatch } 给组件props,它们分别是
- duck 对应的duck实例,可以访问它的 types、selectors、creators等及其它自定义属性
- store 对应完整的Redux store状态,但是不允许直接访问它,而是应通过duck.selector/duck.selectors访问
- dispatch 对应Redux store的dispatch方法
这里将遵循此约定的组件称为DuckComponent,它可以非常方便地与duck结合起来进行复用。
Functional Stateless Component性能优化
当前React还未对纯函数组件进行优化,每次都会触发重新渲染。我们可以利用 purify 来进行简单优化
import { purify } from 'saga-duck'
export default purify(function MyComponent(props){
return <div />
})
purify会提供props浅对比,如果一致则跳过(通过shouldComponentUpdate方法),同时如果判断为DuckComponent(props中同时有duck与store属性),则不会直接对store对比,而是对比duck.selector(store)。
当然,purify也可以用于非函数的React组件
export default purify(class MyComponent extends React.Component{
render(){
return <div />
}
})
动态函数优化
可能你经常会写这样的代码
function Container({duck, store, dispatch}){
return <Foo handler={()=>dispatch(duck.creators.bar())} />
}
也许你已经知道这种情况下的Foo组件只进行浅对比是无效的,因为handler在每次render时都传递一个新的函数。
对于这种只和duck与dispatch相关的函数,我们可以通过memorize来使它变为固定的引用
import { memorize } from 'saga-duck'
const getHandler = memorize((duck, dispatch) => ()=>dispatch(duck.creators.bar()) )
function Container(props){
const handler = gethandler(props)
return <Foo handler={handler} />
}
当然对于传统React组件也是适用的
class Container extends Component{
render(){
const handler = gethandler(this)
return <Foo handler={handler} />
}
}
saga业务逻辑健状性
redux-saga通常只要出错没有try...catch,都会导致退出中止,建议使用redux-saga-catch
库的相关方法进行包装,避免一处错误影响整个业务。
import { takeEvery, takeLatest } from 'redux-saga-catch'