redux是一个可以实现组件间共享数据的React 插件,原理就是在每个组件下都挂载一个store对象,这样可以通过store获取数据,相类似的插件还有vue中的vuex。
redux的运行流程如下:
数据传递方式
组件中传递Action-------->Store------自动转发action到---------->reducers---------->reducer深拷贝原state数据为newState--------->Store转发给组件------组件执行store.subscribe更新store----->组件数据渲染
基础篇涉及以下几个重要API:
createStore(); // 创建store对象
store.getState();//获取store中的数据,defaultState
store.subscribe();//订阅store,更新store数据
store.dispatch();//提交action
代码演示:
// store/index.js
// 创建store
import { createStore } from 'redux'
import reducer from "./reducer";
const store = createStore(
reducer,
// 用于redux插件的配置
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
); // 创建store,图书管理员
export default store
// store/reducer.js
// 笔记本
const defaultState = { // 这是初始值,也是需要在组件间传递的值
inputValue: '',
list: []
};
// reducer 可以接受state,但是不能修改state,因此需要进行深拷贝
export default (state = defaultState, action) => {
if (action.type === 'change_input_value') { // 通过传入的type区分
const newState = JSON.parse(JSON.stringify(state)); // 深拷贝
newState.inputValue = action.value;
return newState;
} else if (action.type === 'add_list') {
const newState = JSON.parse(JSON.stringify(state)); // 深拷贝
newState.list.push(state.inputValue);
newState.inputValue = '';
return newState
}
return state;
}
// 组件
import React, {Component} from 'react'
import "antd/dist/antd.css";
import {Button, Input, List} from "antd";
import store from "./store";
class TodoList2 extends Component {
constructor(props) {
super(props);
// console.log(store.getState()); // 从store中获取数据
this.state = store.getState();
this.handleChange = this.handleChange.bind(this)
this.handleStoreChange = this.handleStoreChange.bind(this)
}
componentDidMount() { // 更新store
store.subscribe(this.handleStoreChange)
}
handleAddClick() { // 增加内容
const action = { // 向reducer传递数据
type: 'add_list'
};
store.dispatch(action);
}
render() {
return (
<div className="wrapper" style={{margin: 'auto'}}>
<Input placeholder="请输入信息"
value={store.getState().inputValue}
onChange={this.handleChange}
style={{width: '300px'}}/>
<Button type="primary" onClick={this.handleAddClick}>添加</Button>
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
style={{width: '300px', marginTop: '10px'}}
bordered
dataSource={this.state.list}
renderItem={(item, index) => (
<List.Item>
{item}
</List.Item>
)}
/>
</div>
)
}
handleChange(e) {
const action = { // 创建action
type: 'change_input_value',
value: e.target.value
};
store.dispatch(action); // 调用action,传给store,store自动转发action到reducer
// console.log(e.target.value);
}
handleStoreChange() { // 更新store
this.setState(store.getState())
}
}
export default TodoList2
redux结构优化
定义一个actionTypes.js统一管理action type<br>
```javascript
export const ADD_LIST = 'add_list'
export const DELETE_ITEM = 'delete_item'
export const CHANGE_INPUT_VALUE = 'change_input_value'
```
使用时,导入这些常量即可。<br>
定义一个actionCreators.js文件统一管理action
```javascript
// 统一管理action
import {CHANGE_INPUT_VALUE} from "./actionTypes";
export const getInputChangeAction = (value) => ({
type: CHANGE_INPUT_VALUE,
value
})
```
使用action
```javascript
import {getInputChangeAction} from './store/actionCreators'
handleChange (e) {
const action = getInputChangeAction(e.target.value);
store.dispatch(action); // 调用action,传给store,store自动转发action到reducer
}
```
评论列表
已有0条评论