【前端学习——react文档】学习react文档笔记(持续更新)

【前端学习——react文档】学习react文档笔记(持续更新)本文详细介绍了 React 中的 JSX 语法 包括大括号的使用规则 Props 的传递与组件间通信 state 和 useStateHook 的使用 以及状态管理 纯函数 key 事件处理 状态提升 受控与非受控组件 ref 和 useEffectHoo 的最佳实践

大家好,欢迎来到IT知识分享网。

jsx语法系列

JSX 中通过大括号使用 JavaScript

可以在哪使用大括号 ?
  • 用作 JSX 标签内的文本<h1>{name}'s To Do List</h1> 是有效的,但是 <{tag}>Gregorio Y. Zara's To Do List</{tag}> 无效。
  • 用作紧跟在 = 符号后的属性:src={avatar} 会读取 avatar 变量,但是 src=“{avatar}” 只会传一个字符串 {avatar}。
使用 “双大括号”

将 Props 传递给组件

 <Avatar person={ 
   { 
    name: 'Lin Lanying', imageId: '1bX5QH6' }} size={ 
   100} /> 
  1. 在子组件中读取 props
    子组件的括号内直接列出他们( 不要忘记 ( 和 ) 之间的一对花括号 { 和 }
function Avatar({ 
     person, size }) { 
    // 在这里 person 和 size 是可访问的 } 

或者通过整个 props 对象,将它解构。

function Avatar(props) { 
    let person = props.person; let size = props.size; // ... } 
  1. 给 prop 指定一个默认值
    默认值仅在缺少 size prop 或 size={
    undefined} 时生效。 但是如果你传递了 size={null} 或 size={0},默认值将 被使用。
  2. 使用 JSX 展开语法传递 props
<Avatar { 
   ...props} /> 

state

既然谈到props,接着看看state

组件需要“记住”某些东西,就需要用state

例如,下面这种不起作用,index的值不会改变

export default function Gallery() { 
    let index = 0; function handleClick() { 
    index = index + 1; } return ( <> <button onClick={ 
   handleClick}> Next </button> <h3> { 
   index + 1} </h3> </> ) 

存在两个原因使得变化不可见:

  • 局部变量无法在多次渲染中持久保存。 当 React 再次渲染这个组件时,它会从头开始渲染——不会考虑之前对局部变量的任何更改。
  • 更改局部变量不会触发渲染。 React 没有意识到它需要使用新数据再次渲染组件。

要使用新数据更新组件,需要做两件事:

  • 保留 渲染之间的数据。
  • 触发 React 使用新数据渲染组件(重新渲染)。
useState

在 React 中,useState 以及任何其他以“use”开头的函数都被称为 Hook
Hooks ——以 use 开头的函数——只能在组件或自定义 Hook 的最顶层调用,你不能在条件语句、循环语句或其他嵌套函数内调用 Hook(遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。——这样React 才知道返回的是哪个 state )。只在 React 渲染时有效

useState里发生了什么?

const [index, setIndex] = useState(0); 
React 如何知道返回哪个 state ?

原因:在同一组件的每次渲染中,Hooks 都依托于一个稳定的调用顺序。只要 Hook 的调用顺序在多次渲染之间保持一致,React 就能正确地将内部 state 和对应的 Hook 进行关联。

这就是为什么 Hook 需要在我们组件的最顶层调用

state特性

State 是隔离且私有的:如果你渲染同一个组件两次,每个副本都会有完全隔离的 state!改变其中一个不会影响另一个。根据组件在 UI 树中的位置(而不是JSX中的位置),React 可以跟踪哪些 state 属于哪个组件。

只要一个组件还被渲染在 UI 树的相同位置,React 就会保留它的 state。
如果它被移除,或者一个不同的组件被渲染在相同的位置,那么 React 就会丢掉它的 state。
并且当你在相同位置渲染不同的组件时,组件的整个子树都会被重置。也就是说如果外层包裹的相同组件的分别是div和section,那么还是会丢掉state

为被移除的组件保留 state ?

React 会使 state 的值始终“固定”在一次渲染的各个事件处理函数内部。你无需担心代码运行时 state 是否发生了变化。【不管时间过了多久,state变量的值在 React 通过调用你的组件“获取 UI 的快照”时就被“固定”了(每一次渲染的 state 值都是固定的)。也就是说即使等到你利用这个state的时候它已经更改过了,你在使用它的时候他的值仍然是更改前(渲染的时候:用户与之交互时状态的快照)的值】

setState

如果你想在下次渲染之前多次更新同一个 state,你可以像 setNumber(n => n + 1) 这样传入一个根据队列中的前一个 state 计算下一个 state 的 函数,而不是像 setNumber(number + 1) 这样传入 下一个 state 值。

当你将setNumber(n => n + 1) 传递给一个 state 设置函数时:
1.React 会将此函数加入队列,以便在事件处理函数中的所有其他代码运行后进行处理。
2.在下一次渲染期间,React 会遍历队列并给你更新之后的最终 state。
在这里插入图片描述


选择 State 结构

如果某两个 state 变量总是一起变化,则将它们统一成一个 state 变量可能更好。
state 妙用——保留初始值的办法(在 state 中镜像 props)
//只有当你 想要 忽略特定 props 属性的所有更新时,将函数的 props “镜像”到 state 才有意义。 function Message({ 
     messageColor }) { 
    const [color, setColor] = useState(messageColor); 

color state 变量被初始化为 messageColor 的 prop 值。如果父组件稍后传递不同的 messageColor 值(例如,将其从 ‘blue’ 更改为 ‘red’),则 color state 变量将不会更新! state 仅在第一次渲染期间初始化。

渲染和提交

在一个 React 应用中一次屏幕更新都会发生以下三个步骤:

  1. 触发
  2. 渲染
  3. 提交

1. 触发一次渲染
有两种原因会导致组件的渲染:

  • 组件的初次渲染
  • 组件(或者其祖先之一)的 状态发生了改变

2. React 渲染你的组件

  • 在进行初次渲染时, React 会调用根组件,创建DOM节点。
  • 对于后续的渲染, React 会调用内部状态,更新触发了渲染的函数组件。(递归地更新这些触发了渲染的组件)

3. React 把更改提交到 DOM 上
在渲染(调用)你的组件之后,React 将会修改 DOM。

  • 对于初次渲染, React 会使用 appendChild() DOM API 将其创建的所有 DOM 节点放在屏幕上。
  • 对于重渲染, React 将应用最少的必要操作(在渲染时计算!),以使得 DOM 与最新的渲染输出相互匹配。
    React 仅在渲染之间存在差异时才会更改 DOM 节点。

4. 浏览器绘制
在渲染完成并且 React 更新 DOM 之后,浏览器就会重新绘制屏幕。

纯函数

例子

 let guest = 0; function Cup() { 
    // Bad:正在更改预先存在的变量! guest = guest + 1; return <h2>Tea cup for guest #{ 
   guest}</h2>; } export default function TeaSet() { 
    return ( <> <Cup /> <Cup /> <Cup /> </> ); } 

https://stackoverflow.com/a/

条件渲染

切勿将数字放在 && 左侧

渲染列表

为什么需要 key?

让我们可以从众多的兄弟元素中唯一标识出某一项。即使元素的位置在渲染的过程中发生了改变,它提供的 key 值也能让 React 在整个生命周期中一直认得它。

key 需要满足的条件

  • key 值在兄弟节点之间必须是唯一的。 不过不要求全局唯一,在不同的数组中可以使用相同的 key。只能指定 父组件内部 的顺序。
  • key 值不能改变,否则就失去了使用 key 的意义!所以千万不要在渲染时动态地生成 key。

如何设定 key 值

  • 来自数据库的数据: 如果你的数据是从数据库中获取的,那你可以直接使用数据表中的主键,因为它们天然具有唯一性。
  • 本地产生数据:可以使用一个自增计数器或者一个类似 uuid 的库来生成 key。

注意

组件不会把 key 当作 props 的一部分。Key 的存在只对 React 本身起到提示作用。如果你的组件需要一个 ID,那么请把它作为一个单独的 prop 传给组件<Profile key={id} userId={id} />

响应事件

事件冒泡:如果你点击任一按钮,它自身的 onClick 将首先执行,然后父级

的 onClick 会接着执行。
在 React 中所有事件都会传播,除了 onScroll,它仅适用于你附加到的 JSX 标签。

调用 e.stopPropagation(),阻止事件进一步冒泡。

不要混淆 e.stopPropagation() 和 e.preventDefault()。它们都很有用,但二者并不相关:

  • e.stopPropagation() 阻止触发绑定在外层标签上的事件处理函数。
  • e.preventDefault() 阻止少数事件的默认浏览器行为

渲染和提交

有两种原因会导致组件的渲染:

  • 组件的 初次渲染。
  • 组件(或者其祖先之一)的 状态发生了改变。

在组件间共享状态——状态提升

实现两个组件的状态始终同步更改——可以将相关 state 从这两个组件上移除,并把 state 放到它们的公共父级,再通过 props 将 state 传递给这两个组件。

受控组件和非受控组件

当组件中的重要信息是由 props 而不是其自身状态驱动时,就可以认为该组件是“受控组件”

Reducer

使用 Context 深层传递参数

ref 引用值

当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 ref 。

ref.current 属性访问该 ref 的当前值。这个值是有意被设置为可变的,意味着你既可以读取它也可以写入它

何时使用 ref ?

在这里插入图片描述

使用ref操作dom

在这里插入图片描述

如何使用 ref 回调管理 ref 列表

不知道会有多少项列表,如何为每个绑定 ref

错误❌

<ul> { 
   items.map((item) => { 
    // 行不通! // Hook 只能在组件的顶层被调用。不能在循环语句、条件语句或 map() 函数中调用 useRef 。 const ref = useRef(null); return <li ref={ 
   ref} />; })} </ul> 

解决方案是将函数传递给 ref 属性。这称为 ref 回调。当需要设置 ref 时,React 将传入 DOM 节点来调用你的 ref 回调,并在需要清除它时传入 null 。这使你可以维护自己的数组或 Map,并通过其索引或某种类型的 ID 访问任何 ref。

也就是在顶层设置一个ref,但这个ref存放了多个节点的ref

  • 将 ref 放在 你自己的 组件上,例如 ,默认情况下你会得到 null。但你可以指定将它的 ref “转发”给一个子组件。
const MyInput = forwardRef((props, ref) => { 
    return <input { 
   ...props} ref={ 
   ref} />; }); 

useEffect

没有依赖数组作为第二个参数,与依赖数组位空数组 [] 的行为是不一致的:

useEffect(() => { 
    // 这里的代码会在每次渲染后执行 }); useEffect(() => { 
    // 这里的代码只会在组件挂载后执行,即首次出现在屏幕上这一阶段。 }, []); 

记法就是:

  • 没有[]表示依赖所有,每次更新渲染都执行
  • 有[]表示没有要参考的组件变化,所以当组件挂载后一直不变化,相当于只在从无到有当前节点的时候执行一次而已

如何移除不必要的 Effect

  • 你不必使用 Effect 来转换渲染所需的数据。当要渲染的数据更新时,React 会把这些变化“提交”到 DOM 中来更新屏幕。然后 React 会执行你的 Effect。如果你的 Effect 也立即更新了这个 state,就会重新执行整个流程。
  • 不必使用 Effect 来处理用户事件。当一个 Effect 运行时,你却不知道用户做了什么(例如,点击了哪个按钮),应该在相应的事件处理函数中处理用户事件。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/138311.html

(0)
上一篇 2025-06-13 20:10
下一篇 2025-06-13 20:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信