【React自制全家桶】九、Redux入手

it2022-06-25  88

一、React项目中为什么要用Redux

  上图:

左图当使用纯React开发稍微大点的项目,因为React数据是瀑布式的,只能通过父子组件传递数据,所以实现关系不大的两React的组件之间的数据传递就会让你非常难受,操作起来非常复杂。如右图,由此应运而生了Redux数据流框架,专门解决数据流问题,

Redux的基本原理就是React的所有组件涉及到的数据全部都存储在共用的Store中,这样所有组件都可以通过Store来改动数据和获取数据,非常方便。

 

二、Redux安装

在已经安装yarn的前提下

 

yarn add redux

  

三、Redux工作流讲解

先上图:

为了方便理解,我将一个redux的操作流程视为从图书馆取书的流程:

1、React Components(借书人)

2、说借一本《React全栈》书(Action Creations就是代表需要进行的操作)

3、Store(图书馆管理员)听到了这句话

4、从reducers(记书本)中查询书在哪放着

5、Store(图书馆管理员)查到(即reducers返回newState)

6、Store(图书馆管理员)将书交给React Components(借书人)(即:将改动后的state发给React Components(借书人))

 

四、Redux使用入门

1、使用谷歌浏览器下载浏览器rudux插件(建议开启***后下载安装)

 

2、在src目录下创建store文件夹

 

3、在store文件夹下创建index.js文件作为redux的入口文件

 

import {createStore} from 'redux'; // 引入reducer import reducer from './reducer'; const store = createStore( reducer, // 显示redux调试工具 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); export default store;

  

4、在store文件夹下创建reducer.js文件作为数据

import {CHANGE_INPUT_VALUE , ADD_TODO_ITEM , DELETE_TODO_ITEM} from './actionTypes'; const defaultState = { inputValue : "", list: [] }; //reducers可以接收state但是绝不能修改state //reducers不能有异步操作也不能有与时间相关的操作,也不能对接收的参数进行修改 //返回纯函数,纯函数指的是:给定固定输入,则输出固定,而且不会有任何副作用 export default (state = defaultState,action) => { // state是上一个store中存储的数据,action是用户发过来的操作请求 // 1、JSON.parse()用于从一个字符串中解析出json对象 // 2、JSON.stringify()用于从一个对象解析出字符串 if (action.type === CHANGE_INPUT_VALUE) { // state深拷贝 const newState = JSON.parse(JSON.stringify(state)); newState.inputValue = action.value; return newState; } if (action.type === ADD_TODO_ITEM) { // state深拷贝 const newState = JSON.parse(JSON.stringify(state)); newState.list.push(newState.inputValue); newState.inputValue = ''; return newState; } if (action.type === DELETE_TODO_ITEM) { // state深拷贝 const newState = JSON.parse(JSON.stringify(state)); newState.list.splice(action.index, 1); return newState; } return state; }

  

5、核心组件中导入store

import React,{Component} from 'react'; import 'antd/dist/antd.css'; import {Input, Button, List} from 'antd'; import store from './store/index'; import {getInputChangeAction, getAddItemAction, getDeleteItemAction} from './store/actionCreators' // import {CHANGE_INPUT_VALUE , ADD_TODO_ITEM , DELETE_TODO_ITEM} from './store/actionTypes'; class TodoList extends Component{ constructor(props){ super(props); this.state = store.getState(); this.handleInputChange = this.handleInputChange.bind(this); this.handleStoreChange = this.handleStoreChange.bind(this); this.handleBtnClick = this.handleBtnClick.bind(this); // 监听store中数据的变化,改变则通过handleStoreChange()函数重新渲染 store.subscribe(this.handleStoreChange) } render(){ return( <div style={{margin:'30px'}}> <div> <Input type="text" value={this.state.inputValue} placeholder='todo info' style={{width:'300px',marginRight:'10px'}} onChange={this.handleInputChange} /> <Button type="primary" onClick={this.handleBtnClick}>提交</Button> </div> <div> <List style={{width:'300px',marginTop:'10px'}} bordered // 数据源 dataSource={this.state.list} renderItem={(item,index) => (<List.Item onClick={this.handleItemDelete.bind(this,index)}>{item}</List.Item>)} /> </div> </div> ) } // 输入框改变 handleInputChange(e){ const action = getInputChangeAction(e.target.value); // 将action派发给store store.dispatch(action); } // 数据重新获取并渲染 handleStoreChange(){ // store.getState()从store中重新取数据 // this.setState()更新数据 this.setState(store.getState()) } // 点击后增添数据 handleBtnClick(){ // 创建action对象 const action = getAddItemAction(); // 将action发给store store.dispatch(action); } handleItemDelete(index){ const action = getDeleteItemAction(index); store.dispatch(action); } } export default TodoList;

  

6、升级——store中创建actionCreators

import {ADD_TODO_ITEM, CHANGE_INPUT_VALUE, DELETE_TODO_ITEM} from "./actionTypes"; export const getInputChangeAction = (value) => ({ type : CHANGE_INPUT_VALUE, value }); export const getAddItemAction = () => ({ type : ADD_TODO_ITEM }); export const getDeleteItemAction = (index) => ({ type : DELETE_TODO_ITEM, index });

  

7、升级——store中创建actionTypes

export const CHANGE_INPUT_VALUE = 'change_input_value'; export const ADD_TODO_ITEM = 'add_todo_item'; export const DELETE_TODO_ITEM = 'delete_todo_item';

  

转载于:https://www.cnblogs.com/piaobodewu/p/9458213.html

相关资源:react-开箱即用最新react全家桶工程

最新回复(0)