我是靠谱客的博主 无私小馒头,最近开发中收集的这篇文章主要介绍react的状态管理以及reduxReact的状态管理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

React的状态管理

1.class组件

在传统的class组件中,react的状态管理大多依赖以下三种方式:

  1. props
  2. state
  3. context

下面来简单说一下以上三种方式

1.props

 子组件一般通过父组件传递的props值来进行相应的展示,自身没有自己的状态。这也造成了一些问题,只有父元素主动触发了props的修改,受控组件的的渲染才会进行相应的改变,这样的应用场景显然太单薄了,受控组件当然也有需求通过自身的一些变化能够触发自身的重新渲染,最常见的例子input受控组件输入框,如何做到输入框的值来自于父组件的props,而当输入框输入内容时又能够更改输入框中显示的值呢?这就要说一说react的设计思路了,基于jsx语法的能够直接书写js代码的组件式开发框架,在react中可以直接灵活的书写js代码,这就有了让js的高阶函数发挥作用的机会了,通过函数的传递,将父组件中更改数据的函数传入子组件中,子组件触发相应的操作时调用该函数,并传入相应的值,就能够做到更改父组件中的数据,这也是函数式编程的优势之一,灵活且强大的抽象能力。这种高阶函数传递的方式也是常说的react子组件向父组件传递值的方式。

 在react中数据是单向流动的,数据只能从父组件到子组件,而通过高阶函数的方式则能够实现将子组件的值传入父组件中。这对于经常使用js的人来说是相当熟悉且友好的

2.state

 子组件一般不接收props,自身内部维护自己的state。组件的重新渲染一般通过调用自己的setState方法进行,这里说一个老生长谈的问题:reactsetState方法到底是同步的还是异步的?答案是两种都有,在不同的情况下会有不同的处理方法,总的来说如果是在react的可控范围内调用该方法,那么该方法就是异步的,这样做的好处是能够批量汇总setState的调用值,进行state的一次性更新,能够减少内部重新渲染的次数,有助于提高性能,由于这个原因,在react的生命周期函数中调用的该方法的的话,此时直接读取state的值是没有更改的,针对这个问题,react也提供了相应的解决办法,setState方法可以跟一个函数,这个函数接收一个参数,这个参数就是当前state的变化汇总,由于是react自己实现的,因此这样并不会导致重新渲染却能够获取正确的state值,而不在react的可控范围内调用该方法的话就只能是同步的,原因也很好理解,因为当前的调用状态react已经不可控了,没法进行异步汇总更新。那么什么情况是可控的什么又是不可控呢,简单来说在reatc的生命周期内触发的话就是可控的,因为调用过程由react控制,而不在生命周期内触发比如在setTimeout中触发就不可控,因为当前调用setState的是浏览器的行为,检测的话也比较简单,只需要判断一下当前函数中的this就行了。

3.context嵌套传值

 典型的生产者消费者模式,用以解决react中祖先组件向子孙组件传递状态时每一层都需要写props的问题,这既不清晰也不优雅。当然这也造成了新的问题,组件树的嵌套会进一步加深,给人的感觉就像回调地域

2.hook函数

class组件存在一些小问题,比如class语法会有一定的复杂度、class组件的生命周期函数都只有一份这就导致了一个组件有太多的副作用操作时需要将逻辑全部写在该生命周期函数中,虽然可以进行方法抽取,但抽取出来函数一般也是与该组件耦合性较深的,因为该函数一般需要当前组件的内部状态作为副作用的参数,或者直接需要该组件的dom对象,此外副作用函数与清除副作用的函数不能在视觉上写在一起,造成了后续维护的麻烦,并且由于js的特性,函数中的this指向问题也比较绕,基于种种原因,react在16版本中推出了hook函数,让以前存在感不是很足的函数组件也能够实现class组件的生命周期函数功能,在实际体验上做到基本一致。

 说一说我知道的hook函数实现原理,由于函数组件不会使用new来创建react组件对象,那么reacthook函数如何实现为特定函数组件服务,并且在特定时期调用特定的方法呢?首先,hook函数是react自己实现的api,这就有很大的操作空间了,react会在内部使用一个栈,用来记录当前被调用的函数组件,如果在函数组件中使用了hook函数,那么react就可以通过当前栈顶函数知道被服务的组件,接着在组件的不同的生命周期触发不同的hook函数体就行了,这也是函数组件重新渲染后会重新执行的原因,函数在栈中执行完成会出栈,下次需要再将组件树重新执行一次就又能够重新入栈,继续hook函数的执行。

 由于有了直接获取服务组件的概念,就不再需要像class组件中那样在组件树书写时就确定context的嵌套关系,可以在子组件需要时使用useContexthook函数来直接获取祖先组件的提供值,并且可以通过多次调用获取多个。各个生命周期hook函数的功能也更加灵活,可以书写多个,副作用函数与取消副作用函数也可以直接写在一起。

 当然基于栈以及重新渲染就重新执行的概念,hook函数也造成了自己的问题,那就是js的陈旧闭包,js中的函数会生成自己的作用域,每一次的函数组件重新执行时里面的变量就重新生成并处于一个新的作用域中,如果里面写的所有hook函数也重新生成执行,这显然是不合适的,但如果不重新执行hook函数本身作用域中的变量就可能是过时失效的了,所以hook函数被设计成了通过依赖来决定是否重新生成的机制。

redux的作用

1.redux的作用

 基于reactcontext机制实现的统一状态管理的工具,将原本在各个组件中分散的状态进行统一管理。redux的操作一般是在当前组件中获取一部分的state状态,当前组件执行了操作后dispatch一个新的action更改任务,reduxreducer获取到更改任务对state进行相应的更改,受到该state更改影响的组件重新渲染。

2.redux的简单实现

// 使用context实现store
import React, { useContext, createContext } from "react";
// 实现store对象
class Store {
constructor(reducer, init) {
// reducer函数,处理不同的派发请求
this.reducer = reducer;
// state, store对象存储的数据
this.state = init;
// 派发任务执行时的监听器
this.listeners = [];
}
// 获取store对象存储的数据
getState = () => {
return this.state;
};
// 派发任务的函数
dispatch = (action) => {
this.state = this.reducer(this.state, action);
this.listeners.forEach((it) => {
it();
});
};
// 添加额外触发器的函数,每一次dispath后都会执行的函数
subscribe = (listener) => {
this.listeners.push(listener);
// 返回一个取消监听的函数
return () =>
(this.listeners = this.listeners.filter((it) => it != listener));
};
}
// 实现redux的createStore方法
function createStore(reducer, init) {
return new Store(reducer, init);
}
// 创建一个provider
let StoreContext = createContext();
// 实现react-redux的Provider组件, 用法<Provider store={store}></Provider>
function Provider({ store, children }) {
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
}
// 实现react-redux的useSelector() hook函数, 从store存储的数据中提取数据
function useSelector(selector) {
let store = useContext(StoreContext);
return selector(store.getState());
}
// 实现react-redux的useDispath() hook函数, 使用store对象派发操作
function useDispatch() {
let store = useContext(StoreContext);
return function (action) {
store.dispatch(action);
};
}
// 实现react-redux的useStore()
hook函数, 直接获取store对象
function useStore() {
return useContext(StoreContext);
}

最后

以上就是无私小馒头为你收集整理的react的状态管理以及reduxReact的状态管理的全部内容,希望文章能够帮你解决react的状态管理以及reduxReact的状态管理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部