(卡老师的简易笔记) 10分钟学会React Hook 1 从数学等式开始 2x + 1 = y 其中x 叫做自变量,y
文章来自卡老师的教学和总结
1 从数学等式开始
2x + 1 = y
- 其中
x
叫做自变量,y
叫做因变量.- 简单说,就是x变化会导致y变化
- 除了
useRef
,其他都可以归类为 自变量/因变量- 自变量:
useState
useReducer
useContext
- 因变量
useMemo
useEffect
useCallback
- 自变量:
从最重要useState
自变量开始
import {useState} from 'react';
export default function App() {
// 1 定义x的方法,并且初始值为 0
const [x,setX] = useState(0);
// 3 定义改变x的方法,每次调用时 都会让x的只+1
const changeX = () => setX(x + 1);
}
return (
// 2 接着定义组件所描述的字符,并将x的值 渲染为li 标签的值
// 4 将changex 绑定为ul的回调函数,点击视图触发更新; x 变化 => 视图变化
<ul onClick={changeX}>
<li>x是{x}</li>
</ul>
)
- 描述一下函数组件.
useState
定义了x,x 的变化导致li
的变化- 所以
useState
是自变量,导致了li
的变化=> 对应了视图变化;
- 所以
现在定义因变量y
- 定义
y = 2x + 1
import {useState} from 'react';
export default function App() {
const [x,setX] = useState(0);
// 1 定义y
const y = 2 * x + 1;
// 3 调用 changeX,触发更新,x变化,y跟着变化 => 视图变化
const changeX = () => setX(x + 1);
}
return (
<ul onClick={changeX}>
<li>x是{x}</li>
{/* 2 也将y渲染为li标签 */}
<li>y是{y}</li>
</ul>
)
- x变化,y跟着变化,=> 视图变化
可以缓存的useMemo
和useCallback
- 可以用
useMemo
和useCallback
分别包裹y
和cahngeX
useMemo
用来缓存一个因变量,需要显式的指定因变量
依赖的自变量
useCallback
缓存一个函数类型的因变量,也需要显式的指定依赖的自变量
import {useState,useMemo,useCallback} from 'react';
export default function App() {
const [x,setX] = useState(0);
const y = useMemo(() => 2 * x + 1,[x]); // 需要显式的指定y依赖于x的变化
// useCallback 缓存一个函数类型的因变量
const changX = useCallback(()=> setX(x + 1),[x]);
}
return(
<ul>
<li>x的值是{x}</li>
<li>y的值是{y}</li>
</ul>
)
- 可以看到使用
useMemo
和useCallback
也是一样的;- 使用
hooks
显式指明因变量 - 使用的时候
y
和changeX
会被缓存下来,只要x不变,始终读取的是缓存的值- 不使用的时候,每次函数组件调用,都会创建新的y和changeX
- 在遇到性能瓶颈之前,都可以不使用这2个 hooks
- 使用
组件的功能不仅描述视图,还能产生副作用 - useEffect
- 副作用:
- 副作用是
fp
中的概念,如果固定的输入 x 一定产生固定的输出 =>纯函数
- 副作用是
function calc(x) {
return 2 * x + 1
}
- 比如这个,x 一定时,输出的结果一定是固定的
但是当引入随机数z
function calc(x) {
const z = Math.random();
return 2 * x + 1 + z;
}
-
结果就不一定是输出决定了,其中 z 就是 副作用
-
比如当x变化后,将当前标题的值修改为x的值,修改标题就是 副作用
-
比如操作
DOM
,请求数据 都是副作用
千呼万唤始出来
import { useState,useEffect} from 'react';
export default function App() {
const [x,setX] = useState(0);
const changeX = () => setX(x + 1);
// 调用useEffect,依赖于x,当x 变化时,将title 赋值为x
useEffect(()=>{
document.title = x
},[x])
}
return (
<ul>
<li>x是{x}</li>
<li>y是{y}</li>
</ul>
)
-
点击调用
changeX
,视图变化也带来了 title 变化 -
总结一下,
useState
定义自变量,useMemo
定义普通因变量,useCallback
定义函数类型的因变量,useEffect
定义有副作用的因变量
进阶: 从useState
到useReducer
- 使用
redux
的理念,将多个state
合并为1个,本质上也是因变量
传递:useContext
- 改进一下我们的组件
import {useState,useEffect} from 'react';
// 1 新建 Count 组件
function Count({data}) {
// 2 接收data作为props,返回斜体的 data
return <i>{data}</i>
}
export default function App() {
const [x,setX] = useState(0);
const changeX = () => 2 * x + 1;
useEffect(()=>{
document.title = x
},[x])
}
return (
<ul>
{// 3 App组件中会返回2个组件,分别将x 和 y 作为 prop传入}
<li>x是<Count data={x}/></li>
<li>y是<Count data={y}/></li>
</ul>
)
-
在
Count
组件内部,传入的props又会作为自变量 作用于视图,count
组件
<i>{data}<i/> <i>{data}<i/>
- 又能作为另一个组件的自变量和因变量
-
如果有n级组件,那么一级传到n级会很麻烦
在一级组件通过
createContext
后,在后续组件需要用到地方通过useContext
可以直接消费一级组件的context
个性化需求 useRef
比如我们想在自变量
和 视图
之间做些是事情
比如,需要奇数次更新时,显示
<li>
,偶数次更新时不显示
需要一个变量,标记当前组件更新的次数,保存标记的变量
- 是因变量? 自变变量?
都不是
只是在路径中起到缓存数据的作用
import {useState,useEffect,useRef } from 'react';
function Count({data}) {
// 2 接收data作为props,返回斜体的 data
return <i>{data}</i>
}
export default function App() {
const [x,setX] = useState(0);
const changeX = () => 2 * 1 + 1;
// 1 先定义 renderCountRef
const renderCountRef = useState(1);
const isOdd = renderCountRef.current % 2 !== 0; // 判断是否是奇数次更新
renderCountRef.current++;
useEffect(()=>{
document.title = x
},[x])
}
return(
<ul>
{/** 3 App组件中会返回2个组件,分别将x 和 y 作为 prop传入 **/}
{isOdd ? <li>x是<Count data={x}/></li> : null}
<li>y是<Count data={y}/></li>
</ul>
)
- 当点击偶数次,不展示
li
转载自:https://juejin.cn/post/7038601532832481293