首页 > 其他分享 >React

React

时间:2024-11-05 21:47:12浏览次数:4  
标签:调用 函数 渲染 React state 组件

渲染原理

React其实是一个从上而下的组件树

React的jsx通过createElement会重新变成js对象,因为js的资源比DOM来的要便宜得多,当组件树都创建完成之后,会进行一个diff算法,对节点进行一个懒更新,其实他循环的时候需要的那个key属性其实就是用来更准确地找到需要更新的地方,更节省资源和效率。

当其中任何一个节点发生变化,state变化,就会对那个节点以及节点下面的子组件进行重新更新。如果想不重新更新可以用memo去包裹组件,当props没改变的情况下就可以不更新。

很多文章都有提到虚拟DOM,其实就是js的组件树对象,我最近看的一篇blog里面说React在逐渐脱离虚拟DOM的说法更倾向于称之为value ui, 意思就是把UI变成了两个可以进行比较的value。

整个过程分为两步:

1. 生成新的组件树js对象,diff比较

2. 提交改变,把对DOM进行渲染

生命周期

1. 组件初始化constructor,初始化state

2. render方法创建虚拟DOM,

3. 调用didmount钩子,这时候一般可以进行一些异步请求

4. 当state和props赋值之后会进行一个虚拟DOM更新,shouldcomponentUpdate方法判断是否需要更新

5. 然后调用didupdate钩子,这时候可以对DOM进行操做

6. component卸载会调用unmount钩子

Fiber架构粗浅理解

react 16之后引入了Fiber的重构算法,之前的是使用了递归的方式去进行diff

1. 使用了链表结构的计算方式,各个节点值之间都有联系,可以中断和回复

2. 加入了调度器,优先渲染对用户影响最大的部分

3. 时间切片可以断断续续的渲染

State理解(写给自己的)

React在渲染组件的时候更多的是考虑组件在树中的位置,如果{isShow && <MyComponent>}

这种情况下切换isShow会让组件显示和消失,他已经消失在组件树原本的位置当中了,组件中的state也会同样的销毁掉

ifA ? <MyComponent para="a" /> : <MyComponent para="b" />

这种情况下组件树中组件的位置没变,只是prop变了,react不会重置state

 

当state变化会触发组件的重新渲染,obj的情况需要re-assign

如果state在组件渲染期间变更则不会更新,会以最后的一次变更为准,防抖模式

State的值不会在一次渲染的内部(函数)发生变化,set之后依旧是原来的值

如果使用闭包的写法调用,则可以保存当前作用域的state数值

只读

渲染必须是纯粹的

可以使用对象展开的语法进行局部更新

需要填充新的对象进去

React在渲染组件的时候更多的是考虑组件在树中的位置,如果{isShow && <MyComponent>}

这种情况下切换isShow会让组件显示和消失,他已经消失在组件树原本的位置当中了,组件中的state也会同样的销毁掉

ifA ? <MyComponent para="a" /> : <MyComponent para="b" />

这种情况下组件树中组件的位置没变,只是prop变了,react不会重置state

需要重置的时候需要加key去让React 明白

当在相同的位置渲染相同的组件时,React 会保留状态。通过将 userId 作为 key 传递给 Profile 组件,使 React 将具有不同 userId 的两个 Profile 组件视为两个不应共享任何状态的不同组件

React如何区别位置

{}一个大括号算一个位置

react 用key来区别不同的component

如下所示T,A,B三人分别对应一个chat聊天框,不加KEY的话聊天框的信息就共享了

Key很重要, 尤其是当需要组件一一对应的时候

f73be7eaa9e4449e9e126927fadebc92.png

Reducer

当state里面包含了过多的增改逻辑(action)的时候我们可以使用reducer封装

reducers 必须是纯粹的, 即纯函数

和用户的交互需要一一对应

cc9d87450ca349049682705890cd9329.png

20ae60235d6246d3a0eeea3175a7eeb6.png

Context

创建context并且传入默认值

export const LevelContext = createContext(6);

使用:const level = useContext(LevelContext);

提供:

<LevelContext.Provider value={level}>

{children}

</LevelContext.Provider>

注意

被<LevelContext.Provider value={level}>包裹的子组件

会去最近的, provider去寻找context的value

Context使用场景

主题,当前账户,状态管理

Ref

Ref是一个react框架访问不到的存储,渲染页面之后它的值也会是不变的

所以如果需要存储一些值,而这些值在显示中不会被用到,就选择Ref

ref可以接受一个函数将多个节点绑定进去

<li

key={cat.id}

ref={node => {

const map = getMap();

if (node) {

// 添加到 Map

map.set(cat.id, node);

} else {

// 从 Map 删除

map.delete(cat.id);

}

}}

>

当想要绑定Ref到自定义的组件

const MyInput = forwardRef((props, ref) => {

return <input {...props} ref={ref} />;

});

const MyInput = forwardRef(function MyInput(props, ref) {

const inputRef = useRef(null);

 

useImperativeHandle(ref, () => {

return {

focus() {

inputRef.current.focus();

},

scrollIntoView() {

inputRef.current.scrollIntoView();

},

};

}, []);

 

return <input {...props} ref={inputRef} />;

});

缓存

组件缓存

我们知道,在父组件重新渲染后,子组件也不得不渲染,就算它其实没啥变化。我们可以通过memo函数包裹子组件,达到缓存的目的,只要props没有变化就不会重新渲染

c5cdfef12d884f9bbdc2a7a5c0eeeb20.jpg

 他是通过object.is比较,简单类型比较值,引用类型(数组,对象,函数)看引用是否改变,经常需要配合useMemo计算缓存和useCallback函数缓存一起用

6c0a95d20110496988b8ea76dbcb2107.jpg

 上面的代码仍然会触发子组件渲染,因为父组件渲染后list会重新赋值

计算缓存

函数缓存

因为函数也是引用类型,当父组件把函数传递给子组件时,如果之后父组件出现了重新渲染,子组件同样得渲染。于是就需要用useCallback

d4d6dd23e4504af7b72ab918a8442a21.jpg

 45fdae2cdc934270963692b52b3215e0.jpg

 父组件操纵子组件

Dom元素

如果需要父组件中获取到子组件的dom的引用,需要使用forwardRef将引用对象传递下去077bc7b7662745c1a78d48a1e90a563c.jpg

996c1a08ef2f44cdb84b6aa6e161416f.jpg

调用子组件方法 

如果有需求,需要父组件调用子组件的方法,可以使用useInperstiveHandler

2dde3b3b356148528323dac7d00e133a.jpg

 它类似于一个把方法绑定到对象的方式,将子方法绑定到父组件的变量对象身上

Redux

slice切片

通过createSlice创建切片, name,初始化,reducer以及extraReducer用于异步请求

定义异步函数的时候需要使用AsyncThunk

d8b5bc8fe1c94a5b81f9d6eb4cb11bf0.png

Store

4f5c403a7a1349fab5a820288f1019fe.png

装载

e075a56db5884b658d624b527c9159d0.png

Hooks

只在组件渲染时生效

隔离且私有

Use开头,只在组件最上面调用,或者其他hook里面调用,不能在hook的回调函数中使用

自定义 Hook 共享的只是状态逻辑而不是状态本身。对 Hook 的每个调用完全独立于对同一个 Hook 的其他调用

名字要清晰,通过名字和input就可以很好地知道这个是做什么的

路由

性能调优

1. 少用内联样式对象

2. 少用匿名函数

3. 记得用key

4. 多用懒加载和memo, useMemo

5. 隐藏显示的话最好用css实现

6. 用Fragment

Styled组件

useTransition

Zustand

SSR

服务器端渲染

首屏快,页面结构不空白有利于搜索引擎的优化

 

 

 

 

 

 

标签:调用,函数,渲染,React,state,组件
From: https://blog.csdn.net/baidu_28505395/article/details/143315286

相关文章

  • 【热门主题】000027 React:前端框架的强大力量
    前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • windows XP,ReactOS系统3.4 共享映射区(Section)---1
    系列文章目录文章目录系列文章目录3.4共享映射区(Section)NtCreateSection()MmCreateSection()MmCreateDataFileSection()NtMapViewOfSection()MmNotPresentFaultSectionView()3.4共享映射区(Section)对于用户空间的映射,一个物理页面通常只属于一个进程,即只被......
  • windows XP,ReactOS系统3.4 共享映射区(Section)---2
    系列文章目录文章目录系列文章目录在ReactOs内核中ROS_SECTION_OBJECT结构体MM_SECTION_SEGMENT结构体SECTION_PAGE_DIRECTORY结构体SECTION_PAGE_TABLE结构体在ReactOs内核中在ReactOs内核中,映射区的数据结构是ROS_SECTION_OBJECT,显然这与Windows中的“......
  • 谈一谈React18的服务端组件
    最近笔者腾出了大把的时间,学习了一下React18。什么是服务器组件React18带来了一个实验性的特性:ReactServerComponents,简称RSC,即服务器组件。服务器组件可能会在React19版本作为稳定特性推出。如果目前就用于生产的话,可能需要注意API在未来的变化情况。什么是服务器......
  • 前端react面试基础知识(II)
    这些问题涵盖了React的很多核心概念和实际应用场景。下面是针对每个问题的详细回答:1.**React项目中,如何动态改变组件的class来切换样式?**  可以通过条件判断或者状态(state)来动态改变组件的class。例如,使用`className`属性与JavaScript表达式结合:  ```jsx......
  • 【ReactPress】一款基于React的开源博客&CMS内容管理平台—ReactPress
    ReactPressGithub项目地址:https://github.com/fecommunity/reactpress欢迎提出宝贵的建议,感谢Star。ReactPress是使用React开发的开源发布平台,用户可以在支持React和MySQL数据库的服务器上架设属于自己的博客、网站。也可以把ReactPress当作一个内容管理系统(CMS)来使......
  • react是什么
    React是一个用于构建用户界面的JavaScript库。它由Facebook开发并维护,广泛用于构建单页应用程序(SPA)和移动应用程序。React的核心思想是通过组件化的方式来构建用户界面,使得代码更加模块化、可重用和易于维护。React的主要特点组件化:React将用户界面划分为多个独立的、可重......
  • 开发 react 技术栈的前台项目,选用 semantic-ui-react 组件库是否是较好的选择
    在前端开发中,合适的UI组件库的选择至关重要,它能在保证交互和视觉一致性的同时,大大提升开发效率。Semantic-UI-React是React技术栈中备受关注的UI组件库之一,以其丰富的组件和友好的API受到了许多开发者的欢迎。然而,是否选择它作为项目的UI组件库需结合多个因素综合考虑......
  • 推荐一个在react项目中为元素添加样式的第三方库(styled-components)(css in js方案)
    1、安装插件pnpm      pnpmistyled-components npm      npminstall styled-componentsyarn        yarn add styled-components2、创建一个js文件用于写样式(模板字符串写法)(1)以App.jsx组件为例,创建一个style.js样式文件,创建组件并暴露//......