安装必要的包
npm install redux react-redux
│ └─ store
│ ├─ actions // actions,文件夹内以模块区分
│ │ ├─ count.js
│ │ └─ person.js
│ ├─ constants.js // action type唯一标识常量
│ ├─ index.js // 入口文件
│ └─ reducers // reducers,文件夹内以模块区分
│ ├─ conut.js
│ ├─ index.js // reducers统一暴露文件,合并reducers
│ └─ persons.js
创建Redux Store
在你的React应用中,你需要创建一个Redux store。这个store将持有整个应用的状态。
// src/store/index.js
import { createStore, applyMiddleware } from "redux";
// 用于支持异步action
import thunk from "redux-thunk";
import reducers from "./reducers";
export default createStore(reducers, applyMiddleware(thunk));
创建Actions
定义action对象中type类型的常量值,消除魔法字符串
// src/store/constants.js
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
创建action,普通action返回对象,异步action返回函数
// src/store/actions/count.js
import { INCREMENT, DECREMENT } from "../constants";
// 普通action的值为object `{type: INCREMENT, data }`
export const increment = data => ({ type: INCREMENT, data });
export const decrement = data => ({ type: DECREMENT, data });
// 异步action的值为函数
export const incrementAsync = (data, time) => {
return (dispatch) => {
setTimeout(() => {
dispatch(increment(data));
}, time);
};
};
创建Reducers
Reducer是一个纯函数,它接收当前的state和一个action,然后返回一个新的state。
// src/store/reducers/conut.js
import {INCREMENT, DECREMENT} from '../constants'
// 初始化状态
const initState = 0;
export default function count(preState = initState, action) {
const { type, data } = action;
switch (type) {
case INCREMENT:
return preState + data;
case DECREMENT:
return preState - data;
default:
return preState;
}
}
// src/store/reducers/persons.js
import { ADD_PERSON } from "../constants";
const initState = [{ id: "001", name: "jona", age: "23" }];
export default function persons(preState = initState, action) {
const { type, data } = action;
switch (type) {
case ADD_PERSON:
// return preState.unshift(data) // 此处不可以这样写,这样会导致preState被改写了,personReducer就不是纯函数了,redux识别不到状态改变,视图不会更新了
return [data, ...preState];
default:
return preState;
}
}
// src/store/reducers/index.js
import { combineReducers } from "redux";
import count from "./conut";
import persons from "./persons";
export default combineReducers({
count,
persons,
});
提供Store给React应用
使用Provider组件将store提供给React应用。这通常在你的应用的顶层进行。
// index.js 或 App.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; // 引入Provider组件
import store from './store'; // 引入store配置文件
import App from './App'; // 引入你的主组件文件
ReactDOM.render(
<Provider store={store}> {/* 将store提供给应用 */}
<App /> {/* 应用组件 */}
</Provider>,
document.getElementById('root')
);
连接React组件和Redux Store
你可以使用connect函数来连接React组件和Redux store。这样,你可以在React组件中访问和修改状态。
// Counter.js 组件文件,展示计数器并允许增加或减少计数器值。
import React from 'react';
import { connect } from 'react-redux'; // 引入connect函数用于连接组件和Redux store。
import { increment, decrement } from './actions'; // 引入action creators。
function Counter({ value, onIncrement, onDecrement }) { // 从props接收value, onIncrement, onDecrement。
return (
<div>
<h1>{value}</h1> {/* 显示当前计数器的值 */}
<button onClick={onIncrement}>+</button> {/* 点击增加计数器值 */}
<button onClick={onDecrement}>-</button> {/* 点击减少计数器值 */}
</div>
);
}
const mapStateToProps = state => ({ // 将state映射到props上。这里我们只需要counter的值。
value: state.counter.value, // 从store的state中获取counter的值。
});
const mapDispatchToProps = dispatch => ({ // 将dispatch方法映射到props上,以便我们可以调用它来分发action。
onIncrement: () => dispatch(increment()), // 当点击增加按钮时分发increment action。
onDecrement: () => dispatch(decrement()), // 当点击减少按钮时分发decrement action。
});
export default connect(mapStateToProps, mapDispatchToProps)(Counter); // 连接Counter组件和Redux store。