从无到有一步一步创建一个react-redux、redux-thunk使用教程:本教程GitHub地址:

https://github.com/chunhuigao/react-redux-thunk

创建react工程

在电脑上找一个文件夹,在命令窗使用create-react-app 创建我的react工程;这一步应该会的
create-react-app study-redux
复制代码
看到下面这个图证明我创建完毕

启动react服务

在创建任务完成后进入我的创建的react工程,然后npm start运行,接着在浏览器http://localhost:3000/我应用该可以看到下面图片的场景

安装redux

要使用redux我需要使用npm将redux包安装到我的react工程中
在react工程的命令窗输入
npm install redux
npm install react-redux
npm install redux-thunk
复制代码
如果报错,请使用淘宝代理cnpm安装。等待安装完毕,从新npm start启动项目

我的工程目录

删除无用的代码

将app.js中html结构代码删除,代码如下:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';class App extends Component {render() {return (<div className="App">{/* <header className="App-header"><img src={logo} className="App-logo" alt="logo" /><p>Edit <code>src/App.js</code> and save to reload.</p><aclassName="App-link"href="https://reactjs.org"target="_blank"rel="noopener noreferrer">Learn React</a></header> */}</div>);}
}export default App;复制代码
这段代码对我学习redux没什么用,我喜欢代码简洁一点,所以删除了

创建第一个组件

在工程目录src/component中创建一个名为hello的文件夹,在hello文件夹中创建一个名为hello.js的文件。
在hello.js写如下代码:
import React, { Component } from 'react'class Hello extends Component {render() {return (<div><h2>学习redux</h2></div>)}
}
export default Hello
复制代码
在app.js中引入hello这个组件
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Hello from './component/hello/hello.js'
class App extends Component {render() {return (<div className="App"><Hello /></div>);}
}export default App;
复制代码
在浏览器中我应该可以看到“学习redux”这句文案了。

添加第一个事件

给hello添加一个按钮,点击按钮可以改变“学习redux”这句文案;hello.js具体代码如下:
import React, { Component } from 'react'
import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {return (<div><h2>{this.state.title}</h2><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}
export default Hello
复制代码

开始使用redux

下面这个流程刚开始接触redux可能云里雾里。但要坚持,跟着我的操作,你一定会看到结果的

index.js引用一下内容

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';import { Provider } from 'react-redux'  //新引入
import {createStore} from 'redux'   //新引入
import rootReducer from './rootReducer.js'  //新引入const store = createStore(rootReducer)
ReactDOM.render(
<Provider store={store}><App />
</Provider>
, document.getElementById('root'));// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();复制代码
redux和react-redux之前安装过,引用后会报错,原因是引入的rootReducer.js这个文件需要创建;

创建rootReducer

在src文件夹创建rootReducer.js文件代码如下:
文件中combineReducers将拆分的页面单独reducer合并为一个大的reducer
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
const rootReducer = combineReducers({helloReducer
})
export default rootReducer
复制代码
这里面引入了一个helloReducer.js,这里我在hello.js同级文件夹创建helloReducer.js

创建helloReducer.js

reducer里面定义页面初始数据,在根据action.type操作state;具体代码如下:
const initState = {name:'hello,redux'
}
export default (state=initState,action) => {switch (action.type) {case 'CHANGE_NAME':return {...state,name:action.text}default:return state;}
}
复制代码
然后将reducer数据绑定到组件中,这里需要用到react-redux中的connect函数

数据绑定到组件

这部分是在hello.js中进行的;具体代码如下:
import React, { Component } from 'react'//引用connect
import {connect} from 'react-redux'import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {
//此处打印this.props应该可以看到helloProp这个对象了,证明数据已经挂在到组件紫红console.log(this.props)let {prop} = this.propsreturn (<div><h2>{this.state.title}</h2><h3>我是来自redux数据{prop.name}</h3><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}//mapStateToProps是connect一个参数, 作用到将store中的数据作为 props 绑定到组件上
const mapStateToProps = (state, ownProps) => {return {helloProp: state.helloReducer//helloReducer是在rootReducer中的名}
}
//通过connect高阶函数绑定数据
export default connect(mapStateToProps)(Hello)
复制代码
数据已经绑定到组件了,怎么操作改变数据呢?需要用到action了

创建helloAction.js

在hello.js同级不目录创建helloAction.js;action主要负责发出动作指令,定义所有事件行为的;具体代码如下:
const helloAction = {changeName:(text)=>({type:"CHANGE_NAME",text:text,mate:'用于改变helloReducer中name值'})
}
export default helloAction
复制代码
文件创建好怎么用呢?数据可以绑定到组件,action也是可以绑定到组件的,使用redux中bindActionCreators,具体代码看hello.js

将action绑定到组件

在hello.js引入新创建的helloAction.js,哎,看代码吧
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
//引入helloAction
import helloAction from './helloAction.js'
import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {//此处打印,应该可以看到actionsconsole.log(this.props)let {prop} = this.propsreturn (<div><h2>{this.state.title}</h2><h3>我是来自redux数据{prop.name}</h3><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}const mapStateToProps = (state, ownProps) => {return {prop: state.helloReducer}
}//使用mapDispatchToProps绑定helloAction
const mapDispatchToProps = (dispatch, ownProps) => {return {actions:bindActionCreators(helloAction,dispatch)}
}
//将mapDispatchToProps作为参数给connect
export default connect(mapStateToProps,mapDispatchToProps)(Hello)
复制代码
改写changeTitle事件,修改redux传过来的数据
changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)// this.setState({//   title:title// })let {actions} = this.propsactions.changeName(title)}
复制代码
效果图
孤例不为证,这个是在hello.js操作helloReducer的数据,不需要redux这么麻烦也可以搞定。下面我使用redux操作一下其他组件修改HelloReducer中的数据
移步GitHub点个start

创建other组件

在component文件夹中创建other文件夹,在other文件夹创建other.js;具体代码如下图
在app.js引入other.js
import React, { Component } from 'react';
import Hello from './component/hello/hello.js'
import Other from './component/other/other.js'
import './App.css';class App extends Component {render() {return (<div className="App"><Hello /><Other /></div>);}
}export default App;复制代码

other具体代码

import React, { Component } from 'react'
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'
import helloAction from '../hello/helloAction.js'class Other extends Component {changeName(){let {helloAction} = this.props;let text = 'other' + (Math.random() *100)helloAction.changeName(text)}render() {let {otherProp} = this.propsconsole.log(this.props)return (<div><h3>我是其他组件</h3><button className="btn" onClick={()=>{this.changeName()}}>我是其他组件的按钮</button></div>)}
}const mapStateToProps = (state, ownProps) => {return {otherProp: state.helloReducer}
}
const mapDispatchToProps = (dispatch, ownProps) => {return {helloAction:bindActionCreators(helloAction,dispatch)}
}
export default connect(mapStateToProps,mapDispatchToProps)(Other)
复制代码
点击按钮,同样可以操作helloReducer.js的数据,mapStateToProps只能绑定一个数据源吗?如果other也有reducer怎么办呢?

组件上绑定多个数据

在other.js同级目录创建otherReducer.js具体代码如下:
const initState = {title:'我是otherReducer数据'
}export default (state=initState,action) => {switch (action.type) {case "CHANGE_TITLE":return {...state,title:action.text}default:return state}
}
复制代码
在rootReducer.js中引用otherReducer.js,rootReducer代码如下:
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
import otherReducer from './component/other/otherReducer.js'
const rootReducer = combineReducers({helloReducer,otherReducer
})
export default rootReducer
复制代码
在other.js的mapStateToProps中绑定reducer数据
const mapStateToProps = (state, ownProps) => {return {helloProp: state.helloReducer,otherProp: state.otherReducer}
}
复制代码
在render打印this.props试试?
  render() {let {helloProp,otherProp} = this.propsconsole.log(this.props)return (<div><h3>我是其他组件</h3><button className="btn" onClick={()=>{this.changeName()}}>我是其他组件的按钮</button><div>{otherProp.title}</div></div>)}
复制代码
到此,可以使用redux了。但这写只能执行同步操作,异步操作需要要结合redux-thunk或者redux-saga了;

redux异步操作

也是写一个简单的例子
在index.js引入redux-thunk
//注释import {createStore} from 'redux'
//新增
import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'//注释 const store = createStore(rootReducer)
//新增
const store = createStore(rootReducer,applyMiddleware(thunk))
复制代码
在component文件夹下创建example文件夹,在example文件夹创建example.js、exampleAction.js、exampleReducer.js具体代码如下:
example.js代码:
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import exampleAction from './exampleAction.js'
class Example extends Component {asyncFn(){let {exampleAction} = this.propsexampleAction.asyncThing()console.log(this.props)}render() {let {exampleProp} = this.propsreturn (<div><h3>异步操作</h3><h4>{exampleProp.text}</h4><button className='btn' onClick={()=>{this.asyncFn()}}>我要进行异步操作</button></div>)}
}
const mapStateToProps = (state, ownProps) => {return {exampleProp: state.exampleReducer}
}
const mapDispatchToProps = (dispatch, ownProps) => {return {exampleAction:bindActionCreators(exampleAction,dispatch)}
}
export default connect(mapStateToProps,mapDispatchToProps)(Example)
复制代码
exampleReducer.js代码:
const initState={text:'我是用来测试异步操作的',sign:null
}
export default (state=initState,action) =>{console.log(action)switch (action.type) {case 'SUCCESS':return {...state,text:action.text,sign:'success'}case 'ERROR':return {...state,text:action.text,sign:'error'}default:return state}
}
复制代码
exampleAction.js
 const exampleAction = {asyncThing:()=>{return (dispatch, getState) =>{// fetch('https://hacker-news.firebaseio.com/v0/jobstories.json')//     .then(res => {//         dispatch(exampleAction.asyncSuccess('我是成功回调'))  //     }).catch(e => {//         dispatch(exampleAction.asyncError('我是成功回调'))  // });setTimeout(() => {let sign = Math.random() >= 0.5 ? true : false;console.log(sign)sign ? dispatch(exampleAction.asyncSuccess('我是成功数据'))  : dispatch(exampleAction.asyncError('我是失败数据'))  }, 2000);}},asyncSuccess:(text)=>({type:'SUCCESS',text:text,mate:'异步成功操作'}),asyncError:(text)=>({type:'ERROR',text:text,mate:'异步成功操作'})
}
export default exampleAction
复制代码
exampleReducer.js同样需要引入rootReduder.js中。
rootReducer代码:
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
import otherReducer from './component/other/otherReducer.js'
import exampleReducer from './component/example/exampleReducer.js'
const rootReducer = combineReducers({helloReducer,otherReducer,exampleReducer
})
export default rootReducer
复制代码
在app.js引入新建是example组件,应该可以看待如下界面
redux异步搞定了。

结束语:

不知我描述的清楚不清楚,希望这篇文章能不能帮到你。本人学识有限,如有文档中不规范或者误人子弟的错误言论,请指正。感谢你花时间阅读这篇文章,谢谢!

转载于:https://juejin.im/post/5c446a7a51882524b4074354

redux-thunk使用教程相关推荐

  1. redux的使用教程

    题目:redux的使用教程 前言:学习react的过程中一定会碰到redux,我在学习redux的时候,每每感觉自己记住了,但是用的时候,感觉总是不知如何写起,或者会用的时候总会出错,所以打算写一篇r ...

  2. Redux 异步数据流-- thunk中间件源码解析

    Thunk 引入背景 这是一个关于Redux异步数据流的故事.引入thunk中间件的完整故事在Redux官方中文文档异步数据流.一句话总结就是:原生Redux只支持同步数据流,所以需要引入中间件(mi ...

  3. Redux 主要知识学习总结

    文章出自个人博客 https://knightyun.github.io/2020/11/29/js-redux-summary,转载请申明 概念 Redux 作为一个状态管理器,可以应用于多种 we ...

  4. React+Redux技术栈核心要点解析(中篇)

    感谢作者郭永峰的授权发布. 作者:郭永峰,前端架构师,现用友网络 FED团队负责人,目前主要负责企业级应用前端技术平台建设工作,在前端工程化实现.Node 应用开发.React技术.移动开发等方向有丰 ...

  5. React + Redux

    相当长一段时间以来,我一直在React和Redux中实现应用程序.在过去的几年里,我写了两本关于它的电子书,并发布了学习React及其生态系统的课程平台.课程平台甚至内置在React和Redux中.我 ...

  6. redux 存值 及 取值 的操作

    项目目录 首先,一个基于React + Redux + React-Router的项目目录可以按照我下方的图片来构建: 其中assets目录用于存放项目的静态资源,如css/图片等,src目录则用于存 ...

  7. redux-thunk使用_Redux Thunk用示例解释

    redux-thunk使用 Redux Thunk is middleware that allows you to return functions, rather than just action ...

  8. 使用Redux在React Navigation App中管理状态

    by Andrea Bizzotto 通过安德里亚·比佐托(Andrea Bizzotto) 使用Redux在React Navigation App中管理状态 (Managing State in ...

  9. Mobx | 强大的状态管理工具 | 可以用Mobx来替代掉redux

    来源简书 电梯直达 https://www.jianshu.com/p/505d9d9fe36a Mobx是一个功能强大,上手非常容易的状态管理工具.就连redux的作者也曾经向大家推荐过它,在不少情 ...

  10. 入门 redux 和 @connect 装饰器

    点击上方 前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 来源:北孤清茶 https://juejin.cn/post/6953866924065292318 首先第一步利用脚手架创 ...

最新文章

  1. 干粮 -- 计算机程序设计艺术(The Art of Computer Design) - 2
  2. bzoj3223 splay
  3. 面向对象三大特性,六个原则
  4. redux ngrx_另一个减少Redux(NGRX)应用程序样板的指南
  5. mysql conflict语句_详细解读MySQL事务
  6. linux操作系统基础篇(四)
  7. 山东科技大学计算机网络_山东科技大学计算机网络共20讲视频
  8. 计算机主板手工,高手在民间 DIY牛人打造实木机箱全纪录
  9. python 水晶报表_水晶报表连接Oracle做数据报表笔记
  10. 河南计算机会考必背知识点,2017年河南物理高中会考知识点大全
  11. 阿里系产品Xposed Hook检测机制原理分析
  12. 计算机分级时无法度量视频播放,无法度量视频播放性能怎么办-无法度量视频播放性能的解决方法 - 河东软件园...
  13. AGI (Analytical Graphics Inc.)
  14. 在Excel数据最后一行下面写入数据的一种方法
  15. Linux 安装 MySQL 8.0 并配置远程登录
  16. 75 [backtrader期货策略]十大经典策略-分时均线交叉策略
  17. BSP-充电名词解释
  18. foxmail皮肤_七大改变!Foxmail 6.5新功能体验
  19. 喜讯 | 南京南方电讯有限公司荣膺“2021中国年度优选雇主”称号
  20. Seata分布式事务控制整合Mybatis-Plus导致事务控制失效

热门文章

  1. SIFT特征提取算法总结
  2. 【linux】Valgrind工具集详解(二):入门
  3. 数据处理过程放在oracle,Oracle存储过程语法及常用函数总结
  4. 源码mysql安装问题_MySQL5.7源码安装问题汇总
  5. 均方根误差不超过_描述数值预报随机误差的利器:随机物理扰动组合方案
  6. python病毒扫描器_基于Python的病毒扫描机制
  7. 驾校计算机岗位管理制度,驾校计算机的规章制度.doc
  8. ansys添加力矩_ansys中的workbench怎么添加力矩
  9. 异步方法顺序调用问题
  10. JS对象转URL参数