之前用react开发了一些模块,对react的使用也更加熟悉了。最近有空,来总结记录一下react相关生态,系统的梳理一下,便于更好的理解和记忆。
参考资料:
Redux
类比Vuex,Redux也是用来解决复杂SPA中的全局状态管理问题。通过对比来一起记忆。
三大原则:
- 单一数据源:整个应用只能有一个唯一的Store
- State 是只读的: 唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象
- 使用纯函数来执行修改: 为了描述 action 如何改变 state tree ,你需要编写 reducers
啥叫纯函数?纯函数要满足三个条件:
- 变量都只在函数作用域内获取,,作为的函数的参数传入,不依赖外部变量。
- 不会产生副作用, 不会改变被传入的数据或者其他数据。
- 相同的输入保证相同的输出。
修改State
只能使用action—>reduce—>返回新的state的方式来修改State
实际开发中我们经常使用Redux-actions这个库来简化写法。
永远不要在reducer中做下边的操作:
- 修改传入参数;
- 执行有副作用的操作,如 API 请求和路由跳转;
- 调用非纯函数,如 Date.now() 或 Math.random()。
在组件中使用State的数据
开发中我们经常会需要从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。此时建议使用 React Redux 库的
connect()
方法,这个方法做了性能优化来避免很多不必要的重复渲染。(这样你就不必为了性能而手动实现 React 性能优化建议 中的 shouldComponentUpdate 方法。)
import { connect as rrConnect } from 'react-redux';
/**
* 通用的redux数据和Action绑定方法
* @param dataMaker
* @param actions
*/
export const connect = (dataMaker = () => {}, actions = () => {}) => Component => {
const mapStateToProps = state => ({data: dataMaker(state)});
const mapDispatchToProps = dispatch => ({actions: bindActionCreators(actions, dispatch)});
Component = rrConnect(mapStateToProps, mapDispatchToProps)(Component);
return Component;
};
还可以使用bindActionCreators
这个方法来通过dispatch将action包裹起来,这样可以通过bindActionCreators
创建的方法,直接调用dispatch(action)(隐式调用)。
传入 Store
所有容器组件都可以访问 Redux store,所以可以手动监听它。一种方式是把它以 props 的形式传入到所有容器组件中。但这太麻烦了,因为必须要用 store 把展示组件包裹一层,仅仅是因为恰好在组件树中渲染了一个容器组件。
建议的方式是使用指定的 React Redux 组件<Provider>
来 魔法般的 让所有容器组件都可以访问 store,而不必显示地传递它。只需要在渲染根组件时使用即可。
// Main router
ReactDOM.render(
<Provider store={store}>
<Router history={history} routes={routes}/>
</Provider>,
document.getElementById('root')
);