Redux
Redux是 JavaScript 应用程序的可预测状态容器。
随着项目代码的不断丰富,项目中状态和业务逻辑分散在每个模块里。这让组件的重复使用变得更加困难,也让组件的数量越来越臃肿。Redux 会尝试拆分 程序数据 和 业务逻辑,将它们放在 React 自己的容器中,这样 React 就可以专注于对 视图的管理 了。这让你的软件变得更灵活。
Redux的优缺点:
优缺点并不全面
优势:
1、数据流流动很自然,因为任何 dispatch 都会导致广播,需要依据对象引用是否变化来控制更新粒度。
2、如果充分利用时间回溯的特征,可以增强业务的可预测性与错误定位能力。
缺点:
1、action和reducer太繁琐。一套或者几套action和reducer的组合,看起来很不错,但是一旦功能和需求多了,action和reducer就会很混乱,如果管理不善,都不能愉悦的写代码了。
2、store和state的模棱两可。没有严格的定义哪些存store,哪些存internal state。
3、dispatch是同步的,而且dispatch没办法确认action是否执行成功。
并不是所有情况下 Redux 都是明智的选择,应用 Redux 的场景:
* 你有着相当大量的、随时间变化的数据
* 你的 state 需要有一个单一可靠数据来源
* 你觉得把所有 state 放在最顶层组件中已经无法满足需要了
一、安装
更目录下运行命令安装 redux
npm install --save redux
二、编辑代码
1、React 项目
代码框架主要延用的是上一节 webpack4+react 配置出来的项目代码。
项目github: https://github.com/Lyh97/wenpack4-react
2、action
(1) 在 src下创建 constants 文件夹,其中创建 actionType.js 文件。
actionType.js
export const HELLO_SET = 'HELLO_SET';
(2) src 下创建 action 文件夹,其中创建 index.js 和 hello.js
hello.js
import * as actionTypes from '../constants/actionTypes'; export function setHello(hello) { return { type: actionTypes.HELLO_SET, hello }; };
index.js
import { setHello } from './hello'; export { setHello };
3、reducers
在 src 下创建 reducers 文件夹,其中创建 hello.js 以及 index.js。
hello.js
import * as actionTypes from '../constants/actionTypes'; const initialState = []; export default function(state = initialState, action) { switch (action.type) { case actionTypes.NAME_SET: return setHello(state, action); } return state; } function setHello(state, action) { const { hello } = action; return [ ...state, ...hello ]; }
index.js
import { combineReducers } from 'redux'; import name from './hello'; export default combineReducers({ hello });
4、stores
src 下创建 stores 文件夹,其中创建 configureStore.js
configureStore.js
import { createStore, applyMiddleware } from 'redux'; import rootReducer from '../reducers/index'; import { createLogger } from 'redux-logger'; const logger = createLogger(); const createStoreWithMiddleware = applyMiddleware(logger)(createStore); export default function configureStore(initialState) { return createStoreWithMiddleware(rootReducer, initialState); }
5、组件中的使用
src/index.js也需要编辑:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import AppTest from './App'; import * as serviceWorker from './serviceWorker'; import configureStore from './stores/configureStore'; import * as actions from './actions'; import { Provider } from 'react-redux'; const hello = 'Hello Word !!'; const store = configureStore(); store.dispatch(actions.setName(hello)); ReactDOM.render( <Provider store={store}> <AppTest /> </Provider>, document.getElementById('root')); serviceWorker.unregister();
我将 redux 用在了我的 App.jsx 组件里 我在其中通过 {this.props.hello} 应用了 redux 中的变量 ,我的 App.jsx 是这么写的。
import React from 'react'; import { connect } from 'react-redux'; class AppTest extends React.Component { constructor(props) { super(props); this.state = { a: 2 } } render() { return ( <div> <p>{this.state.a}</p> {this.props.hello} </div> ) } } function mapStateToProps(state) { return { hello : state.hello } } export default connect(mapStateToProps)(AppTest);