接下来我们按照使用原生 React,使用 Redux 和使用 React-Redux的顺序分别实现一个 Counter 计数器的功能。
3.1 原生 React 实现 import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class Counter extends Component { constructor(props) { super(props); this.state = { value: 0 }; // 状态数据 } render() { return ( <div> <p>state: {this.state.value}</p> <button onClick={() => this.handleIncrement()}>+1</button> <button onClick={() => this.handleDecrement()}>-1</button> </div> ); } // 处理方法 handleIncrement() { let curVal = this.state.value + 1; this.setState({value: curVal}); } handleDecrement() { let curVal = this.state.value - 1; this.setState({value: curVal}); } } // 渲染 ReactDOM.render(<Counter />, document.getElementById('root')) 3.2 使用 Redux 实现 import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; // 接收 action 并处理,签名:(state, action) => newState function reducer(state = {value: 0}, action) { let curVal = state.value; switch (action.type) { case 'INCREMENT': return {value: curVal+1}; case 'DECREMENT': return {value: curVal-1}; default: return state; } } // 创建 Redux store const store = createStore(reducer); const render = () => ReactDOM.render( <div> <p>state: {store.getState().value}</p> {/* dispatch 通知 store 改变数据 */} <button onClick={()=>{store.dispatch({type: 'INCREMENT'})}}>+1</button> <button onClick={()=>{store.dispatch({type: 'DECREMENT'})}}>-1</button> </div>, document.getElementById('root') ) render(); // 订阅 store,状态改变时更新 UI store.subscribe(render); 3.3 使用 React-Redux 实现 import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; import { Provider, connect } from 'react-redux'; // 接收 action 并处理 function reducer(state = {value: 0}, action) { let curVal = state.value; switch (action.type) { case 'INCREMENT': return {value: curVal+1}; case 'DECREMENT': return {value: curVal-1}; default: return state; } } // 定义一个 UI 组件,用于展示数据 class CounterUI extends Component { render() { // 数据来源于 props const {value, handleIncrement, handleDecrement} = this.props; return ( <div> <p>state: {value}</p> <button onClick={handleIncrement}>+1</button> <button onClick={handleDecrement}>-1</button> </div> ); } } // 定义一个 容器组件,用于与 Redux store 交互 // 将 Redux state 按需注入到 UI 组件的 props function mapStateToProps(state) { return { value: state.value } } // 将 Redux actions 按需注入到 UI 组件的 props function mapDispatchToProps(dispatch) { return { handleIncrement: () => dispatch({type: 'INCREMENT'}), handleDecrement: () => dispatch({type: 'DECREMENT'}) } } // 使用 connect 方法基于 UI组件 生成一个 容器组件 const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(CounterUI); const store = createStore(reducer); // 使用 Provider 作为根组件,使得所有子组件都能访问到 store ReactDOM.render( <Provider store={store}> <CounterContainer /> </Provider>, document.getElementById('root') ) 4. 小结Redux 和 React-Redux 专门设计了约束和约定,导致代码量不见得减少,甚至还可能增加了。简单的项目看不出有什么优势,但在构建一定规模的企业级项目时,这些约束和条条框框,会有利于项目的维护和管理。正如 Java,有些人认为过于啰嗦,但这正是它严谨的体现!