react 简单实现 redux 管理数据
2023-03-23 本文已影响0人
暴躁程序员
一、简单实现 redux 管理数据
- 安装 redux
npm install redux -S
- 创建 store
新建 src\store\index.js
import { createStore } from 'redux';
import reducer from './reducer';
const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
- 创建 reducer
新建 src\store\reducer.js
// 初始化store数据
const defaultStore = {
username: '',
};
// 深拷贝,用于创建新state
const deepClone = (obj) => {
const result = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === 'object') {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key]);
} else {
result[key] = obj[key];
}
}
}
}
return result;
};
// 注意:reducer 不可直接修改prevState,需要返回新state
const reducer = (prevState = defaultStore, action) => {
console.log(prevState, action);
switch (action.type) {
case 'change_username':
const newState = deepClone(prevState);
newState.username = action.value;
return newState;
default:
return prevState;
}
};
export default reducer;
- 创建组件,使用 store
新建 src\pages\test\index.js
import React, { Component } from 'react';
import store from '../../store';
class Test extends Component {
constructor(props) {
super(props);
this.state = {
username: store.getState().username,
};
}
render() {
return (
<>
<div>
<label htmlFor="uname">用户名:</label>
<input id="uname" type="text" value={this.state.username} onChange={this.handleChange.bind(this)} />
</div>
</>
);
}
componentDidMount() {
store.subscribe(this.storeUsernameChange.bind(this));
}
handleChange(e) {
const action = {
type: 'change_username',
value: e.target.value,
};
store.dispatch(action);
}
storeUsernameChange() {
this.setState((prevState) => ({
username: store.getState().username,
}));
}
}
export default Test;
二、 简单实现 redux 管理数据的步骤
1. 定义 store 数据
- 在 store 中定义数据
// 初始化store数据
const defaultStore = {
username: '',
};
- 在组件的 constructor 构造函数中,通过 store.getState()获取 store 中数据并赋给组件的 state,用 state 数据渲染页面
constructor(props) {
super(props);
this.state = {
username: store.getState().username,
};
}
render() {
return (
<>
<div>
<label htmlFor="uname">用户名:</label>
<input id="uname" type="text" value={this.state.username} onChange={this.handleChange.bind(this)} />
</div>
</>
);
}
2. 修改 store 数据
- 在组件中的改变 store 数据的方法中定义 action,通过 store.dispatch 方法将 action 发送给 reducer,action 中包括区分标识 type,和 新值 value
handleChange(e) {
const action = {
type: 'change_username',
value: e.target.value,
};
store.dispatch(action);
}
- 在 reducer 中,获取并解析 action,完成将 action 中的新值覆盖 store 中 state 的旧值操作,并 return 新的 state,不可直接改变 prevState,需要在 prevState 备份的基础上修改
const reducer = (prevState = defaultStore, action) => {
console.log(prevState, action);
switch (action.type) {
case 'change_username':
const newState = deepClone(prevState);
newState.username = action.value;
return newState;
default:
return prevState;
}
};
- 在组件中 componentDidMount 生命周期中通过 store.subscribe 可监听到 store 中 state 数据改变,以此来改变组件中 state 的数据
即:在 reducer 中 return 新的 state 后会触发组件 componentDidMount 生命周期中的 store.subscribe 的回调函数 this.storeUsernameChange,在 storeUsernameChange 中通过 store.getState() 获取 store 中的新值来更改组件中的 state 数据
componentDidMount() {
store.subscribe(this.storeUsernameChange.bind(this));
}
storeUsernameChange() {
this.setState((prevState) => ({
username: store.getState().username,
}));
}