【React】React——redux

这篇具有很好参考价值的文章主要介绍了【React】React——redux。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🚩🚩🚩
💎个人主页: 阿选不出来
💨💨💨
💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记.
💨💨💨
💎目前开发的专栏: JS 🍭Vue🍭React🍭
💨💨💨

Redux理解

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

redux是什么

  1. redux是一个专门用于做状态管理的JS库(不是react插件库)。
  2. 它可以用在react,angular,vue等项目中,但基本与react配合使用。
  3. 作用:集中式管理react应用中多个组件共享的状态。

redux的使用场景

  1. 某个组件的状态,需要让其他组件可以随时拿到(共享)。
  2. 一个组件需要改变另一个组件的状态(通信)。
  3. 总体原则:能不用就不用,如果不用比较吃力才考虑使用。

redux的三大原则

  • state以单一对象存储在store对象中
  • state只读(每次都返回一个新的对象)
  • 使用纯函数reducer执行state更新

redux基本使用

下载redux包

npm i redux

代码结构
react项目reducers文件夹,React,react.js,javascript,前端

store.js文件专门用于创建并配置store并暴露

//引入createstore,用于创建store对象
import {legacy_createStore as createStore} from 'redux'
// 引入reducer
import reducer from './reducers'

const store = createStore(reducer)

export default store

actions文件夹存放多个为指定组件生成的action对象。

reducers文件夹存放多个为指定组件服务的reducer纯函数。

constant.js文件用于定义action对象中type类型的常量值,便于管理,防止单词的拼写错误。

例:

export const INCREMENT = 'increment'

Redux的三个核心概念

Redux的工作流

  • View在redux中会派发action方法
  • action通过store的dispatch方法会派发给store
  • store接收action,连同之前的state,一起传递给reducer
  • reducer返回新的数据给store
  • store去改变自己的state

react项目reducers文件夹,React,react.js,javascript,前端

1.action

Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。

const ADD_TODO = 'ADD_TODO'
{
	type: ADD_TODO,
	data: 'Bilid my first Redux app'
}

action本质为JavaScript普通对象。

action内必须包含 type 属性,值为字符串,表示将要执行的动作,作为唯一标识。

type属性外,action对象的结构完全由你自己决定,通常会传入 data属性,值为某个组件向reducer函数操作state时传的参数。

在模块化开发中,一个组件可能会需要多个action对象,通常按照下方的写法。

const INCREMENT = 'INCREMENT'
export const increment = data =>({type: INCREMENT,data})
...

异步action

例如:点击一个按钮,三秒后让一个count数值加一。

当点击按钮后,组件内通过 store.dispatch 将action对象派发给store。

我们在action中返回一个定时器,3秒后调用同步action触发 dispatch执行加动作。

export const incrementAsync = (data,time) =>{
    return (dispatch)=>{
        setTimeOut(()=>{
            dispatch(increment(data))
        })
    }
}

由于redux本身不支持异步操作。react给我们提供了一个插件 redux-thunk 可以让redux拥有异步操作的能力。

用法:

store.js文件下

import {legacy_createStore as createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk
...
export default createStore(reducer,applyMiddleware(thunk))

2.reducer

reducer用于将store发过来的action完成并将结果返回给store,他有两个作用:初始化store和更新store。

reducer接收两个参数preState(旧状态)和action(动作)并返回一个newState(新状态)。

(previousState, action) => newState

初始化状态

const initState = 0 //初始化状态

reducer纯函数

function count(preState=initState,action){
	// 从actions对象中获取:type,data
    const {type,data} = action
    //根据type决定如何加工数据
    switch(type){
        case INCREMENT:
            return xxx
        ...
        default:
        	return preState
    }
}

注意:redux的reducer是一个纯函数。纯函数是一类特别的函数。

纯函数的规则:

  • 不能改写参数数据。
  • 不会产生任何副作用,例如网络请求,输入和输出设备。
  • 不能调用Date.now()或Math.random()等不纯的方法。

例如:当我们要对store里的一个数组添加一个对象时:

错误的写法:

preState.unshift(data)

此时,preState这个实参被改写了,reducer不在是纯函数。

正确的写法:

使用对象展开运算符

[data,...preState] 创建了一个新数组。

combineReducers

Redux应用中只有一个单一的store。当多个组件都需要用到store时,便于数据逻辑处理,我们需要使用reducer组合。

redux提供了 combineReducers()工具类,组合多个reducer。

import {combineReducers} from 'redux'
//引入多个reducer
import reducer1 from './reducer1'
import reducer2 from './reducer2'
...
export default combineReducers({
	reducer1,
	reducer2
})

3.store

前文我们知道了使用action描述“发生了什么”,使用 reducers来根据action更新state的用法。

而 store 就是action 和 reducer 之间的桥梁。

store的创建

//引入createstore,用于创建store对象
import {legacy_createStore as createStore} from 'redux'
// 引入reducer
import reducer from './reducers'

const store = createStore(reducer)

createStore第一个参数传入reducer,第二个参数为可选的,用于设置state初始状态。

Store的职责

  • 维持应用的state;
  • 提供 getState()方法获取state;
  • dispatch(action) 更新state;
  • subscribe(listener)注册监听器;
  • subscribe(listener)返回的函数注销监听器;

这里需要再强调一下:Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

为了让用户监听应用数据改变,Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。

在src/index.js入口文件中:

import store from './redux/store'
...
store.subscribe(()=>{
    root.render(<App/>)
})

react-redux

本库并不是 Redux 内置,需要单独安装,是Redux官方提供的React绑定库。

安装

npm i react-redux

redux将组件分为了UI组件容器组件两类:

  1. UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
  2. 容器组件:负责和redux通信,将结果(采用父子通信)传给UI组件。

Provider

<Provider store> 使组件层级中的 connect() 方法都能够获得 Redux store。

在src/index.jsx文件下:

...
root.render(
	<Provider store={store}
		<App/>
	</Provider>)

目的:让 <App> 所有的后代容器组件都能接收到store。

Connect

用于连接React组件与Redux store。

connect(mapStateToProps,mapDispatchToProps)
  • mapStateToProps(state, [ownProps]): stateProps] (Function)

    • 映射状态。
    • 该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。
    • 如果定义该参数,组件会监听redux store的变化,只要store发生改变,mapStateToProps就会被调用。
  • mapDispatchToProps(dispatch, [ownProps])

    • 映射操作状态的方法。

    • mapDispatchToProps可以是一个Function,也可以是Object,作用是绑定action创建函数到props上。

    • 如果传递的是一个对象,那么每个定义在该对象的函数都将被当作Redux action creator,而且这个对象会与 Reduxstore绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中;

    • 如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与action creator 以某种方式绑定在一起。

例:

头部的引入:

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {
    increment,
    decrement,
    } from '../../redux/actions/count'

mapDispatchToProps返回值为函数时:

connect(
	state=>(count:state.count),
	dispatch=>({
		increment:number=> dispatch(increment(number)),
		decrement:number=> dispatch(decrement(number))
	})
)

mapDispatchToProps返回值为对象时:

采用了对象的简写形式

connect(
	state=>(count:state.count),
	{increment,decrement}
)

react-redux的开发者工具

redux-devtools-extensionredux这个插件是官方提供的可以查看状态的ui插件,让我们在很多组件的情况下,也能知道每个组件的数据情况,非常贴心。

安装

 npm i redux-devtools-extension

配置文章来源地址https://www.toymoban.com/news/detail-791806.html

import {composeWithDevTools} from 'redux-devtools-extension'
...
const store = createStore(reducer,composeWithDevTools(applyMiddleware(thunk)))

到了这里,关于【React】React——redux的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Gitee 上传项目到仓库(上传文件夹)

    1.首先打开仓库,点击下载压缩包  2.将下载的压缩包解压,并打开,在当前目录下打开 1.在文件当前目录打开git bash     2.初始化git 该命令会生成一个隐藏的.git文件夹  如果不是第一次使用,没有必要使用该指令 3.将项目放入该目录下。如果是更改项目,则覆盖原文件 4.添

    2024年02月16日
    浏览(48)
  • 【绝对清楚】Flask项目结构(有项目文件夹详细对照说明)

    插个目前实现的登录页面~😄 之前看了很多很多的Flask框架的项目结构,了解到它是一个高度灵活的轻量级web框架,意思就是项目的结构不像Django那样有着固定的模式,而是可以根据开发者的爱好进行设计。这也就给想用正儿八经的一种结构写一个网站带来了困扰。好在看了

    2024年02月02日
    浏览(52)
  • VisualStudio解决方案多个文件夹将项目分类

    见过好多大项目,一个解决方案好多个项目,网站、动态库、测试等。放在不同的文件夹下,感觉很好。下面介绍一下方法。 首先创建一个空白解决方案 会自动创建MultiFolder解决方案目录。 新建解决方案文件夹 解决方案文件夹不会创建对应的真实目录,需手工在解决方案目

    2024年02月10日
    浏览(75)
  • [github+Windows]从github下载指定项目的单个文件或文件夹

    通过搜索发现,网页上大多流传的是Linux如何从github下载单个文件夹,对于小白来说,不想费力气地安装SVN、gitzip等等工具,将github项目中的单个文件夹下载到Whindows本地,当然是越简单越好。 通过网上查找发现了一个github下载单个文件夹的简单工具,是网页版,将网站打开

    2024年01月19日
    浏览(49)
  • git如何仅合并项目下的某个文件夹

    假设目前在做的一个项目名为demoproject,目前版本为v1.0.0,标准开发都是在demoproject上进行的,但是有一个客户需要做定制化,需要将项目中的一些信息改为客户的,于是基于demoproject拉了一个v1.0.0-custom,然后将这个v1.0.0-custom交付给了客户。 过了一段时间,客户又提了新的需

    2024年01月21日
    浏览(77)
  • React 18 迁移状态逻辑至 Reducer 中

    参考文章 对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,可以 将组件的所有状态更新逻辑整合到一个外部函数中 ,这个函数叫作 reducer 。 随着组件复杂度的增加,将很难一眼看清所有的组件状态更新逻辑。例如,下面

    2024年02月10日
    浏览(61)
  • vue前端获取项目下的静态资源文件夹中的文件并下载

    前端项目/public/static/image文件夹下,两张图片,因为不会经常改变所以做成静态资源 从项目中获取这两张图片 html: 前端项目的 publicstaticfaultFile文件夹中放入模板文件: 实现效果: 代码: 前端下载使用 a 标签的自带的download下载 参考文章:require.context()的用法详解

    2024年02月12日
    浏览(80)
  • IDEA创建Spring,Maven项目没有resources文件夹

    有时新建Spring或Maven项目时,会出现目录中main下无resources文件夹的情况,来一起解决一下: FIles|Project Structure 在Modules模块找到对应路径,在main下创建resources,右键main,选择新文件夹 输入文件名resources,点击OK 找到刚才创建的文件夹,右键,选择设置为Resources 点击Apply,O

    2024年02月11日
    浏览(86)
  • 解决创建的vue项目没有router,view文件夹

    出现问题如图,没有router,view等文件夹 错误原因:创建的vue项目没有router,view文件夹是因为创建项目时的 Please pick a preset: 这个问题选错了,也就是第一个问题 如图所示,选择第三个 接下来的很多选择如图(不详写) 之后创建出来的就有了 ,如图

    2024年02月12日
    浏览(58)
  • Keil5在已有项目中导入文件夹(文件或模块),后编译,头文件找不到问题

    如果你是以及成功导入文件后,但是编译时发现头文件找不到,可以直接从第二部分看起 ** 导入头文件时注意,注意,注意路径问题要和导入文件时的路径一致,(应该不是本项目下的刚导入的文件夹的路径;虽然我们在导入文件后此路径下看是有这个文件夹,但是这个只是个虚拟的文

    2024年02月11日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包