为什么我想要使用redux?

  前段时间初步上手了react,最近在使用react的过程中发现对于组件之间通信的需求比较迫切,尤其是在axios异步请求后端数据的时候,这样的需求是特别强烈的!举个例子:

 
// 厂家报告到货
class ReportArrivalGoods extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            columns:tableHead.ReportArrivalGoods,//这里是初始化的表头,内容较多,不显示出来了
            data: []
          };
    }
    componentDidMount(){
     axios(
        {
            method: 'get',
            url: 'http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods'
        })
        .then(
            res => {    
         this.setState(
                  data:NewState
            );
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
    }
    render(){
        return(
            <Table
            style={{width: '100%'}}
            columns={this.state.columns}
            data={this.state.data}
            border={true}
            maxHeight={tableMaxHeight}
          />
        );
    }
    
}
 

  我们聚焦于下面的componentDidMount()函数

    componentDidMount(){
     axios(
        {
            method: 'get',
            url: 'http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods'
        })
        .then(
            res => {    
         this.setState(
                  data:NewState
            );
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
    }

  这是大家都很熟悉的react生命周期钩子函数,我做了这样一件事:页面渲染完向后台请求数据并显示到页面上。但是用过axios的都知道,他跟ajax一样,都是异步的,也就说,你发处请求后就会立即执行后面的代码了,等你请求结果回来了才会执行then()和catch()。一开始我简单粗暴的直接把整个函数体写进了钩子中,实现是没问题了,可是要使用钩子函数请求不同数据的组件有5个,要是每个组件都写这么一长串代码,一方面不好看,另一方面重复代码太多了。于是我想到了把这段函数体封装起来,于是就有下面的代码

//webservice数据请求函数
function AxiosGet(desinationURL){
axios(
{
method: 'get',
url: desinationURL
})
.then(
res => { );
}
)
.catch(
error => {
console.log(error);
}
);
}

  可是要是封装了怎么设置我组件的state呢?机智的我想到了个办法,在组件内部创建一个带参函数modifyState(),在使AxiosGet()函数时将modifyState()函数作为参数传入AxiosGet()并在AxiosGet()内部将res.data作为参数传modifyState()从而达到setstate的目的。说起来有点绕,用代码说话

//webservice数据请求函数
function AxiosGet(desinationURL,ApplyNewState){
axios(
{
method: 'get',
url: desinationURL
})
.then(
res => {
ApplyNewState(res.data);
}
)
.catch(
error => {
console.log(error);
}
);
}

  上面是组件外部的数据请求函数,下面的是组件内部的钩子函数和用于传入获取数据的函数

  modifyState(NewState){
this.setState(
{
data:NewState
}
);
}
componentDidMount(){
AxiosGet('http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods',
this.modifyState
);
}

  恩,明眼人应该已经看懂了,我巧妙的通过在组件内部将函数传出的方式完成了state的更新,问题虽然解决了,但是这样操作着实麻烦,要是能在组件外部更新组件的state就好了。有人要说了,状态提升啊!为所有的组件创建一个父组件,在父组件中统一更新状态并通过props的形式传入子组件。恩,这确实是个办法,但是父组件就没有表达出了特别的意思了,就好像div一样,没有语义化,有没有更好的方式呢?百度搜搜react的state,来了来了,他来了,灯灯灯灯!redux闪亮登场!

Redux使用七步走

  此处对于redux的知识不做讲解了,我懂得也就那样,redux官网上教程很清晰,可以直接过去学,我主要讲讲redux在react中的使用。如标题所说,只需要七步。众所周知,在redux中,最重要的东西就三个

{

动作:action,

动作处理函数:reducer,

状态仓库:store

}

想必redux官方教程过了一遍的人都能轻松理清其中关系与具体运行吧,那么问题来了,怎么在react中把组件们的state和store给他绑定上呢?网上帖子一大堆,但是跟我之前那篇中说的一样,抄来抄去,没有真正讲到小白的点子上,有的还抄错了导致读者误解,这里我从小白视角做出最贴切的讲解,相信大家听完手敲一遍也就懂了。我是用create-react-app搭建的开发环境,这里不做赘述。话不多说,上代码!目录结构如图所示:

第一步:安装依赖:

npm i redux react-redux -s

第二步:创建action

// /actions/test.js

export const PLUS='PLUS';

export function plusActionCreator(){
return{
type:PLUS
}
}

第三步:创建reducer

//  /reducers/test.js

import {PLUS} from '../actions/test' const initState={count:0}; export function plusReducer(state=initState,action){
switch(action.type){
case PLUS:{
return
       {
count:state.count+1;//此处返回的state只是plusReducer这个小范围内的state,理解这一点很重要!!!
       }
    }
    default:return state;
  }
}
 

第四步:创建store

// /index.js

const reducer=combineReducers({plus:plusReducer});//这里需要传入json对象才行,对象名代表来自哪个reducer
var store=createStore(reducer);

  上面是redux部分,大家应该很熟悉了,此时也到了最重要的部分:react和redux的结合。需要说明一下,react的组件我们现在分为展示组件和容器组件两类,展示组件负责界面呈现,容器组件负责为展示组件管理state。展示组件的所有state通过props传入。

第五步:创建展示组件

// /index.js

function Test (props){
return(
<div>
<p>总计数:{props.count}</p>
<button onClick={props.plus}>加一</button>
</div>
);
}

第六步:通过react-redux提供的connect方法生成容器组件

// /index.js

const CollectionComponent=connect(
(state)=>{
return{
count:state.plus.count//这里需要注意,各个小版块的state是通过combinereducers中命名的json对象名做了分隔的
                    //此处的json对象count与展示组件中的props.count是对应关系
}
},
(dispatch)=>{
return{
plus:bindActionCreators(plusActionCreator,dispatch)
       //此处的json对象plus与展示组件中的props.plus方法也是对应关系
} } )(Test);//此处的Test与展示组件名也是对应关系

  这里很关键,首先const CollectionComponent,这个CollectionComponent就是我们所需要的容器组件。

  connect(read,write)(destination)函数有三个参数read、write和destionation(抽象名,为了方便理解这么叫),read的目的就是从store中返回我们要的state,write的目的是传入action来更新state,destination用来绑定到指定的展示组件。

第七步:通过react-redux提供的Provider组件搭建react和redux数据交互的桥梁

// /index.js

ReactDOM.render(
  <Provider store={store}>//这里把之前创建的store传给Provider,这样store中的state就能传达到容器组件中了
<CollectionComponent/>//由于第六步忠已经把展示组件绑定到了容器组件上了,所以此处只需写容器组件即可
  </Provider>
  ,document.getElementById('root'));

OVER!通过这个小demo即可完成一个简单的累加器。最后贴上完整源码,嘿嘿嘿,yes!

// /reducers/test.js

import {PLUS} from '../actions/test'

const initState={count:0};

export function plusReducer(state=initState,action){
switch(action.type){
case PLUS:{
return {
count:state.count+1
}
}
default:return state;
}
}
// /actions/test.js

export const PLUS='PLUS';

export function plusActionCreator(){
return{
type:PLUS
}
}
// /index.js

//react
import React from 'react'
import ReactDOM from 'react-dom'
//redux
import {connect,Provider} from 'react-redux'
import {bindActionCreators,combineReducers,createStore} from 'redux'
import {plusReducer} from './reducers/test'
import {plusActionCreator} from './actions/test'
//呈现部分
function Test (props){
return(
<div>
<p>这里是count:{props.count}</p>
<button onClick={props.plus}>加一</button>
</div>
);
}
//redux部分
const reducer=combineReducers({plus:plusReducer});//这里需要传入json对象才行
var store=createStore(reducer); const CollectionComponent=connect(
(state)=>{
return{
count:state.plus.count//这里需要注意,各个小版块的state是
//通过combinereducers中命名的json对象名做了分隔的
}
},
(dispatch)=>{
return{
plus:bindActionCreators(plusActionCreator,dispatch)
}
}
)(Test); ReactDOM.render(
<Provider store={store}>
<CollectionComponent/>
</Provider>
,document.getElementById('root'));

最后再给个小彩蛋吧,今天刚捣鼓的react-router的小demo,也是嵌套在上面的代码中的。

//react
import React from 'react'
import ReactDOM from 'react-dom'
//redux
import {connect,Provider} from 'react-redux'
import {bindActionCreators,combineReducers,createStore} from 'redux'
import {plusReducer} from './reducers/test'
import {plusActionCreator} from './actions/test'
//router
import { BrowserRouter,Switch,Route,NavLink } from 'react-router-dom';
//呈现部分
function Test (props){
return(
<div>
<p>这里是count:{props.count}</p>
<button onClick={props.plus}>加一</button>
</div>
);
}
//redux部分
const reducer=combineReducers({plus:plusReducer});//这里需要传入json对象才行
var store=createStore(reducer); const CollectionComponent=connect(
(state)=>{
return{
count:state.plus.count//这里需要注意,各个小版块的state是
//通过combinereducers中命名的json对象名做了分隔的
}
},
(dispatch)=>{
return{
plus:bindActionCreators(plusActionCreator,dispatch)
}
}
)(Test); ReactDOM.render(
<Provider store={store}>
<BrowserRouter >
<Switch>
<Route path="/class/classmates">
<div>QianYingLi,HaoWu,ZhouHuiFan</div>
<NavLink to="/class" activeClassName="fillInClassNameHere">
redirect to class
</NavLink>
</Route>
<Route path="/class">
<div>高一二</div>
<NavLink to="/class/classmates" activeClassName="hurray">
redirect to classmates
</NavLink>
</Route>
<Route path="/">
<CollectionComponent/>
</Route>
</Switch>
</BrowserRouter >
</Provider>
,document.getElementById('root'));

react中使用redux简易案例讲解的更多相关文章

  1. 在react中使用redux并实现计数器案例

    React + Redux 在recat中不使用redux 时遇到的问题 在react中组件通信的数据是单向的,顶层组件可以通过props属性向下层组件传递数据,而下层组件不能向上层组件传递数据,要实 ...

  2. react系列(五)在React中使用Redux

    上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...

  3. 在React中使用Redux

    这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

  4. react中对于redux的封装

    const createStore = (reducer)=>{ //默认的state对象 let state = {}; //将所有订阅的事件存在在这个数组中 let listeners = ...

  5. 在React中使用Redux数据流

    问题:数据流是什么呢?为什么要用数据流? 答案:1.数据流是我们的行为与相应的抽象 2.使用数据流帮助我们明确了行为的对应的响应 问题: React与数据流的关系 1.React是纯 V 层的前端框架 ...

  6. React+Redux学习笔记:React+Redux简易开发步骤

    前言 React+Redux 分为两部分: UI组件:即React组件,也叫用户自定义UI组件,用于渲染DOM 容器组件:即Redux逻辑,处理数据和业务逻辑,支持所有Redux API,参考之前的文 ...

  7. php中foreach()函数与Array数组经典案例讲解

    //php中foreach()函数与Array数组经典案例讲解 function getVal($v) { return $v; //可以加任意检查代码,列入要求$v必须是数字,或过滤非法字符串等.} ...

  8. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  9. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

随机推荐

  1. 前端面试题——html与css基础篇

    整理一波html和css的面试题,侧重基础,希望明天面试能用到~(╥╯^╰╥) 一.HTML部分 1.浏览器页面有哪三层构成,分别是什么,作用是什么? 构成:结构层.表示层.行为层分别是:HTML.C ...

  2. Python的未来发展方向

    Python是一种跨平台的计算机程序设计语言. 是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开发. ...

  3. 23种设计模式之装饰器模式(Decorator Pattern)

    装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...

  4. Spring Data JPA 梳理 - JPA是什么

    总结: JPA是java的标准,不是Spring的标准 java标准中一般通过Meta-INF文件规范开发层面的事情,JPA也不例外,使用persistence.xml JPA定义了Entity 到 ...

  5. java 对数组进行截取组合操作

    1.使用skip跳过和limit限制组合,示例: Integer skip = (page.getPageNum() - 1) * page.getPageNum(); Integer limit = ...

  6. S2-052 漏洞复现

    Structs2框架已知的漏洞编号如下: S2-005 S2-009 S2-016 (含S2-013) S2-019 S2-020 S2-021 S2-032 S2-037(含S2-033) DevM ...

  7. linux下安装Elasticsearch

    一.简单介绍: Elasticsearch提供了近乎实时的数据操作和搜索功能,es集群中所有节点可以一起提供索引和搜索功能,能够相互发现彼此和自动地加入到集群中 二.基础概念: 1.索引: 表征的文档 ...

  8. IDEA 学习笔记之 1.5已经过时问题

    1.5已经过时问题: apache-maven-3.5.0\conf\settings.xml添加: <profile> <id>jdk-1.8</id> < ...

  9. Java 从入门到进阶之路(七)

    在之前的文章中我们介绍了一下 java 中的对象和类,接下来我们来看一下 Java 中的方法重载. 在显示生活中,我们肯定会遇到这样一个问题,那就是我们再商场买东西的时候在付账时的选择.如下 A:在收 ...

  10. BUUCTF刷题记录(Web方面)

    WarmUp 首先查看源码,发现有source.php,跟进看看,发现了一堆代码 这个原本是phpmyadmin任意文件包含漏洞,这里面只不过是换汤不换药. 有兴趣的可以看一下之前我做的分析,http ...