美文网首页
React Hooks

React Hooks

作者: 一个记事本 | 来源:发表于2022-03-04 11:14 被阅读0次

    Hoooks:

    . Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
    . 使用 Hook 其中一个目的就是要解决 class 中生命周期函数经常包含不相关的逻辑,但又把相关逻辑分离到了几个不同方法中的问题。

    1、useState:

    const [count, setCount] = useState(0)
    

    count:变更名
    setCount:更新方法:

    setCount(count + 1) 
     //或者
    setState(item => {
      return {item + 1};
    });
    
    惰性初始 state
        const [state, setState] = useState(() => {
            // 组件的初始渲染中起作用,有些需求要在初始时做复杂的计算做为state初始值。
            return count + counts + 10;
        });
    
    问:

    React 怎么知道 useState 对应的是哪个组件,因为我们并没有传递 this 给 React。(更新数据时都会调用一次组件,也就是会再执行一次函数组件,那么count值为什么可以保存上次的呢?)

    解:

    React 保持对当先渲染中的组件的追踪,每个组件内部都有一个「记忆单元格」列表。它们只不过是我们用来存储一些数据的 JavaScript 对象。当你用 useState() 调用一个 Hook 的时候,它会读取当前的单元格(或在首次渲染时将其初始化),然后把【指针】移动到下一个。这就是多个 useState() 调用会得到各自独立的本地 state 的原因。

    个人理解:闭包(因为组件都被「记忆单元格」【指针】引入了)。

    函数组件也是一个闭包,其中定义的count变量做为闭包私有变量会被useState中强引用,而等到数据更新再次执行函数组件时,会把强引用变量值给到相同变量名。

    2、useEffect :

    useEffect( () => {} )
    
    说明:

    1.useEffect会在第一次渲染及【每次更新】后延迟执行
    2.useEffect可当做componentDidMount(挂载完成),componentDidUpdate(更新完成) 和 componentWillUnmount(组件卸载前) 这三个生命周期函数的组合。
    3.与 componentDidMount 或 componentDidUpdate 不同,使用 useEffect 调度的 effect 不会阻塞浏览器更新屏幕,这让你的应用看起来响应更快。
    4.useEffect的参数为一个函数(异步),React 会保存这个函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它(闭包机制)。
    ## 需要清除的 effect:componentWillUnmount(组件卸载前)在哪做? ##
    为保持代码的紧密性,所以 useEffect 的设计是在同一个地方执行。如果你的 effect 返回一个函数,React 将会在执行清除操作时调用它:

    useEffect( () => { return () => {//这里做需要清除的事件} } )
    
    Effect性能优化:

    在某些情况下,每次渲染后都执行清理或者执行 effect 可能会导致性能问题。
    在 class 组件中

    在 class 组件中,我们可以通过在 componentDidUpdate 中添加对 prevProps 或 prevState 的比较逻辑解决:
              componentDidUpdate(prevProps, prevState) {
                    if (prevState.count !== this.state.count) {  //如果state中count值有变化,那么就更新document.title
                            document.title = `You clicked ${this.state.count} times`;
                    }
                }
    

    在函数组件中

    在函数组件中,设置useEffect 的第二个可选参数即可解决:
                    useEffect(() => {
                        document.title = `You clicked ${count} times`;
                    }, [count]); // 仅在 count 更改时更新document.title
    
    useEffect(()=>{
            console.log('useEffect第二个参数为[]时,当前函数仅在组件挂载和卸载时执行');
            return () => {
                console.log('我要被销毁了');
            }
        },[]) // useEffect第二个参数为[]时,当前函数仅在组件挂载和卸载时执行
    

    3、createContext(挂载) & useContext(解析)

    useContext类似props

    1、创建一个 React 的 上下文 createContext
    const MyContext = React.createContext(defaultValue) //defaultValue 是传入的默认值。
    //如果匹配不到最新的 Provider 则会使用默认值,默认值一般只有在对组件进行单元测试(组件并未嵌入到父组件中)的时候,比较有用。
    
    2、父组件引入了实例,并且通过 MyContext.Provider 将子组件包装,并且通过 Provider的value 将父组件方法提供出去。
    <MyContext.Provider value={{ setStep }}>
         <子组件 />
    </MyContext.Provider>
    
    3、子组件通过useContext解析父组件提供的方法,从而达到子组件中可调用及修改父组件的方法和state。
    const { setStep } = useContext(MyContext);
    

    useReducer:

    1、useState 的替代方案。
    2、useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为[你可以向子组件传递 dispatch 而不是回调函数

    Hook 规则:

    1. 只在最顶层使用 Hook,不要在循环,条件或嵌套函数中调用 Hook
    2. 只在 React 的函数组件中调用 Hook,不要在普通的 JavaScript 函数中调用 Hook。
    3. Hook 规则插件来强制执行上两条规则:

    npm install eslint-plugin-react-hooks --save-dev 
    
    // 你的 ESLint 配置
    {
      "plugins": [
        // ...
        "react-hooks"
      ],
      "rules": {
        // ...
        "react-hooks/rules-of-hooks": "error", // 检查 Hook 的规则
        "react-hooks/exhaustive-deps": "warn" // 检查 effect 的依赖
      }
    }
    

    相关文章

      网友评论

          本文标题:React Hooks

          本文链接:https://www.haomeiwen.com/subject/hcomkrtx.html