React学习计划-react-hooks补充

React Hooks

1. 使用hooks理由

  1. 高阶组件为了复用,导致代码层级复杂
  2. 生命周期的复杂

2. useState(保存组件状态)

复制代码
const [state, setstate] = useState(initialState)

3. useEffect(处理副作用)和useLayoutEffect(同步执行副作用)

  1. 使用方式:

    useEffect(() => {
    // effect
    return () => {
    // cleanup
    };
    }[依赖的状态;空数组,表示不依赖])

  2. 说明:

  • 不传入依赖:对比componentDidMount生命周期,表示初始加载完后执行
  • 传入依赖:对比componentDidMountcomponentDidUpdate生命周期,表示加载完后和更新完成后执行
  • 回调函数内return函数,对比componentWillUnmount销毁生命周期
  1. 示例:

    useEffect(()=>{
    const timer = setInterval(()=>{
    console.log('这是定时器')
    }, 1000)
    return ()=>{
    console.log('componentWillUnmount销毁时触发')
    clearInterval(timer)
    }
    },[name])

  2. useEffectuseLayoutEffect区别:

简单来说就是调用时机不同,useLayoutEffect和原来componentDidMount & componentDidUpdate一致,在react完成DOM更新后马上同步调用代码,会阻塞页面渲染。useEffect则是在整个页面渲染完才会调用代码

官方优先建议使用useEffect

在实际使用时如果想避免页面抖动 (在useEffect里修改DOM很有可能出现)的话,可以把需要操作的DOM的代码放在useLayoutEffect里,在这里做DOM操作,这些DOM修改会和react做出的更改一起被一次性渲染到屏幕上,只有一次回流、重绘的代价

4. useCallBack(记忆函数)

防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数变化了,才重新声明一次

复制代码
var handleClick = useCallback(()=>{
  console.log(name)
},[name])

<button onClick={()=>handleClick()}>点击</button>

// 只有name改变后,这个函数才会重新声明一次
// 如果传入空数组,那么就是第一次创建被缓存,如果name后期改变了,拿到的还是老name
// 如果传第二个参数,每次都会重新声明一次,拿到的就是最新的name

5. useMemo(记忆组件)(可以理解为Vue的计算属性)

useCallBack的功能完全可以由useMemo所取代,如果你想通过使用useMemo返回一个记忆函数也是完全可以的。

复制代码
useCallback(fn, inputs) is equivalent to useMemo(()=> fn, inputs)

唯一的区别是:useCallback不会执行第一个参数函数,而是将它返回给你,而useMemo会执行第一个函数并将函数执行结果返回给你。所以在前面的例子中,可以返回handleClick来达到存储函数的目的。

所以useCallback常用记忆事件函数,生成记忆后的事件函数并传递给子组件使用。而useMemo更适合经过函数计算得到一个确定的值,比如记忆组件。

复制代码
const getFilterList = useMemo(
  ()=> list.filter(item => item.name.toUpperCase().includes(text.toUpperCase())),
  [list, text] // 如果list和text变化
  )

6. useRef(保存引用值)

  1. 设置ref属性值

    const myRef = useRef(null)

  2. 用于缓存一个变量值

    const [name, setName] = useState('zhangsan')
    var mycount = useRef(0)
    <button onClick={()=>{
    setName('lisi')
    mycount.current++
    }}>点击
    {name}-{mycount}

7. useReduceruseContext(减少组件层级)

  1. useContext用于组件通信,接收父组件传入的值

    // 父组件
    import React from 'react'
    var GlobalContext = React.createContext()

    function App(){
    <GlobalContext.Provider value={{
    name: '张三',
    age: 20,
    changeAge: (value) => {
    setAge(value)
    }
    }}>

    </GlobalContext.Provider>
    }

    // 子组件内
    function Child(){
    const text = useContext(GlobalContext)
    }

  2. useReducer:实现Reduxreducer的功能,应用在组件通信中

    const reducer = (prevState, action)=>{
    const newState = { ...prevState }
    switch(action.type){
    case 'add':
    newState.count ++
    return newState
    case 'minus':
    newState.count --
    return newState
    default:
    return prevState
    }
    }
    const initialState = {
    count: 0
    }
    // FC中
    const [state, dispatch] = useReducer(reducer, initialState)

    <button onClick={()=>{
    dispatch({
    type: 'minus'
    })
    }}>-
    {state.count}
    <button onClick={()=>{
    dispatch({
    type: 'add'
    })
    }}>+

8. 自定义hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。

必须以use开头吗?必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含其内部Hook的调用,React将无法自动检查你的Hook是否违反了Hook的规则

相关推荐
sunoo-22929 分钟前
51单片机学习Day2:数码管动态扫描、定时器与中断系统深度总
单片机·嵌入式硬件·学习·51单片机
宣宣猪的小花园.33 分钟前
【机器学习】从机理建模到数据学习:机器学习究竟替代了什么
人工智能·学习·机器学习
泯泷39 分钟前
手搓JSVM第 12 篇:完整最小 JSVM 实现与源码设计复盘
前端·javascript·前端框架
上海心泾国际物流有限公司43 分钟前
我在几个医疗器械仓库记下的一组温湿度数据
经验分享·笔记·学习·健康医疗·交通物流
for_ever_love__1 小时前
python基础语法学习: requirements.txt
开发语言·python·学习
默_笙1 小时前
🍔 给 AI 发一张结构化表格(下):从"自由发挥"到"按格填空"的输出驯服指南
前端·javascript
泯泷1 小时前
手搓JSVM第 11 篇:打包、模块与 CLI:把 VM 产物变成可运行文件
前端·javascript·前端框架
泯泷1 小时前
手搓JSVM第 10 篇:对象、数组与属性访问
前端·javascript·前端框架
for_ever_love__1 小时前
python基础语法学习: 动态类型
开发语言·python·学习
泯泷1 小时前
手搓JSVM第 9 篇:闭包:函数如何记住外部变量
前端·javascript·前端框架