React | React组件化开发(二)

简介: React | React组件化开发(二)

四、React组件插槽用法

React中的插槽(slot)

  • 在开发中 我们抽取了一个组件 但是为了让这个组件具备更强的通用性 我们不能将组件中的内容限制为固定的div span等等这些元素
  • 我们应该让使用者可以决定某一块区域到底存放什么内容

88a443a8b0804ae89e3cee2a2c764679.png

  • 这种需求在Vue当中有一个固定的做法是通过slot来完成的 那么在React中呢?
  • React对于这种需要插槽的情况非常灵活 有两种方案可以实现
  • 组件的children子元素
  • props属性传递React元素

children实现插槽

  • 每个组件都可以获取到props.children: 它包含组件的开始标签和结束标签之间的内容.

6e4f639da9cd4eb8924d5dea2c14f24a.png

39f2572fa99f46049553b97dad574956.png

props实现插槽

  • 通过children实现的方案虽然可行 但是有一个弊端: 通过索引值获取传入的元素很容易出错 不能精准的获取传入的原生
  • 另外一个种方案就是使用 props 实现
  • 通过具体的属性名 可以让我们在传入和获取时更加的精准

8eaa94e9556a40aaa239e66ce53a8f43.png

8e96b0e2185349a7b918c6f528ae8a3c.png

五、React非父子的通信

Context应用场景

  • 非父子组件数据的共享:
  • 在开发中 比较常见的数据传递方式是通过props属性自上而下(由父到子)进行传递
  • 但是对于有一些场景: 如一些数据需要在多个组件中进行共享(地区偏好、UI主题、用户登录状态、用户信息等)
  • 如果我们在顶层的App中定义这些信息 之后一层层传递下去 那么对于一些中间层不需要数据的组件来说 是一种冗余的操作


  • 我们实现一个一层层传递的案例:


  • 我这边顺便补充一个小的知识点:Spread Attributes

033c7250cbae416c8eedfb8cb3258114.png

但是 如果层级更多的话 一层层传递是非常麻烦 并且代码是非常冗余的

  • React提供了一个API:Context
  • Context 提供了一种在组件之间共享此类值的方式 而不必显式地通过组件树的逐层传递 props
  • Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据 如 当前认证的用户 主题或首选语言

Context相关API

React.createContext

  • 创建一个需要共享的Context对象
  • 如果一个组件订阅了Context 那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的context值
  • defaultValue是组件在顶层查找过程中没有找到对应的Provider 那么就使用默认值

b475572c88b8481eb60e7d6df17c22aa.png

Context.Provider


  • 每个 Context 对象都会返回一个 Provider React 组件 它允许消费组件订阅 context 的变化
  • Provider 接收一个 value 属性 传递给消费组件
  • 一个 Provider 可以和多个消费组件有对应关系
  • 多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据
  • 当 Provider 的 value 值发生变化时 它内部的所有消费组件都会重新渲染

9c2e7c30ac284547aeaa991e2243bf50.png

Class.contextType


  • 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象
  • 这能让你使用 this.context 来消费最近 Context 上的那个值
  • 你可以在任何生命周期中访问到它,包括 render 函数中

c7335df72caa436f88ede45d9e17b07c.png

Context.Consumer


  • React 组件也可以订阅到 context 变更.这能让你在 函数式组件 中完成订阅 context
  • 这里需要 函数作为子元素(function as child)这种做法
  • 这个函数接收当前的 context 值,返回一个 React 节点

71fc8285c9f842abbd0e2db0e55283ea.png

  • 什么时候使用Context.Consumer?
  • 当使用value的组件是一个函数式组件时
  • 当组件中需要使用多个Context时

六、setState的使用详解

为什么使用setState

开发中我们并不能直接通过修改state的值来让界面发生更新

  • 因为我们修改了state之后 希望React根据最新的State来重新渲染界面 但是这种方式的修改React并不知道数据发生了变化
  • React并没有实现类似于Vue2中的Object.defineProperty或者Vue3中的Proxy的方式来监听数据的变化
  • 我们必须通过setState来告知React数据已经发生了变化


在组件中并没有实现setState的方法,为什么可以调用呢?


  • 原因很简单,setState方法是从Component中继承过来的

5971b22a7a174a558cb0a7bbd91b4037.png

setState异步更新

  • setState的更新是异步的?
  • 最终打印结果是Hello World
  • 可见setState是异步的操作 我们并不能在执行完setState之后立马拿到最新的state的结果

2bd5057b65984e6096ef0d0ff6fe184e.png

  • 为什么setState设计为异步呢?
  • setState设计为异步其实之前在GitHub上也有很多的讨论
  • React核心成员(Redux的作者)Dan Abramov也有对应的回复 有兴趣的同学可以参考一下


  • 总结:setState设计为异步,可以显著的提升性能
  • 如果每次调用 setState都进行一次更新 那么意味着render函数会被频繁调用 界面重新渲染 这样效率是很低
  • 最好的办法应该是获取到多个更新 之后进行批量更新


  • 如果同步更新了state 但是还没有执行render函数 那么state和props不能保持同步
  • state和props不能保持一致性 在开发中产生很多的问题

如何获取异步的结果

  • 如何可以获取到更新后的值呢?
  • setState(partialState, callback)
  • setState接受两个参数: 第二个参数是一个回调函数 这个回调函数会在更新后会执行
  • setState的回调

42ab288f11104032b2a466789a94f44e.png

  • 当然,我们也可以在生命周期函数

7b5956a69e91479fa4302237ba7da3c9.png

setState一定是异步吗?(React18之前)

  • 在setTimeout中的更新

d297b612cc5d473588c474238b16d72d.png

原生DOM事件

6367862007f14f4a937a93376d73277b.png

  • 其实分成两种情况:
  • 在组件生命周期或React合成事件中,setState是异步
  • 在setTimeout或者原生dom事件中,setState是同步

setState默认是异步的(React18之后)

  • 在React18之后 默认所有的操作都被放到了批处理中(异步处理)

c1eb053b0cf54717a4b1e58b939aedf5.png

  • 如果希望代码可以同步拿到 则需要执行特殊的flushSync操作

f611af08bd6249ed855bc926b7892357.png

相关文章
|
3月前
|
开发框架 前端开发 JavaScript
从零开始学习React Native开发
React Native是一种基于React框架的移动端开发框架,使用它可以快速地构建出高性能、原生的移动应用。本文将从零开始,介绍React Native的基础知识和开发流程,帮助读者快速入门React Native开发,并实现一个简单的ToDo应用程序。
|
2月前
|
JavaScript 前端开发 算法
js开发:请解释什么是虚拟DOM(virtual DOM),以及它在React中的应用。
虚拟DOM是React等前端框架的关键技术,它以轻量级JavaScript对象树形式抽象表示实际DOM。当状态改变,React不直接操作DOM,而是先构建新虚拟DOM树。通过高效diff算法比较新旧树,找到最小变更集,仅更新必要部分,提高DOM操作效率,降低性能损耗。虚拟DOM的抽象特性还支持跨平台应用,如React Native。总之,虚拟DOM优化了状态变化时的DOM更新,提升性能和用户体验。
30 0
|
4月前
|
存储 移动开发 前端开发
【第35期】一文学会React-Router开发权限
【第35期】一文学会React-Router开发权限
46 0
|
10天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
4天前
|
设计模式 前端开发 API
写出易维护的代码|React开发的设计模式及原则
本文对React社区里出现过的一些设计模式进行了介绍,并讲解了他们遵循的设计原则。
|
17天前
|
存储 人工智能 开发框架
【AI大模型应用开发】【AutoGPT系列】0. AutoGPT概念及原理介绍 - Agent开发框架及ReAct方法
【AI大模型应用开发】【AutoGPT系列】0. AutoGPT概念及原理介绍 - Agent开发框架及ReAct方法
22 0
|
20天前
|
前端开发 API 开发者
React这些新特性在开发效率上有哪些改进
【4月更文挑战第18天】React 18 提升开发效率,引入新Root API `createRoot`优化挂载,支持渐进式升级,减少迁移成本。新增性能工具如Profiler API和Concurrent Mode,自动化批处理提高性能,减少重渲染。服务器组件优化加载速度,减轻客户端负担。开发者可更高效构建和优化React应用。
73 6
|
28天前
|
JavaScript 前端开发 API
Vue和React,哪个在移动端开发更适合呢
【4月更文挑战第10天】Vue和React在移动端各有优势。Vue以其简单易用、渐进式开发和性能优化吸引开发者,适合初学者和快速迭代项目。而React凭借强大的生态系统、组件化开发模式和卓越性能,尤其在复杂应用和依赖特定库时更具优势。选择应基于项目需求、团队技术栈及性能要求,可先进行技术调研和原型开发。
22 4
|
29天前
|
前端开发
react使用ant desgin 组件实现便利开发
react使用ant desgin 组件实现便利开发