美文网首页
React - Hook

React - Hook

作者: 闪电西兰花 | 来源:发表于2020-08-15 22:17 被阅读0次
    • Hook是16.8的新增内容,可以在不写 class组件的情况下使用 state及其他特性,比如状态变化、生命周期等,还可以在无需修改组件结构的情况下复用状态逻辑,可以将组件中相互关联的部分拆分成更小的函数,阅读体验更简洁
    • 使用 Hook要新建函数组件,并从 React中引入 useState方法,初始化结构如下:
    // src/components/HookTest.js
    import React, {useState} from 'react';
    
    export default function HookTest () {
      return (
        <div></div>
      )
    }
    
    • 使用 useState 实现一个计数器,记录点击按钮的次数
    import React, {useState} from 'react';
    
    export default function HookTest () {
    
      // useState(initialState)是一个方法,该方法返回一个只包含2项的数组
      // 解构数组后第0项表示状态,我们初始化了这个状态值为0,第1项是更新状态值的方法 
      const [count, setCount] = useState(0)
      return (
        <div>
          <p>点击了{count}次</p>
          <button onClick={() => {setCount(count + 1)}}>点击</button>
        </div>
      )
    }
    
    • 再举一个例子感受下 Hook,当一个函数组件有多个状态时的使用,这里有一个水果列表,点击列表项即选中当前水果然后展示在页面上,同时还有一个输入框,可输入并点击“新增”按钮给水果列表新增水果项
    // src/components/HookTest.js
    import React, {useState} from 'react';
    
    export default function HookTest () {
    
      // useState(initialState)是一个方法,该方法返回一个数组
      // 解构数组后第0项表示状态,我们初始化了这个状态值为0,第1项是更新状态值的方法 
      const [count, setCount] = useState(0)
    
      // 页面展示的选中水果,默认初始值为'Lemon'
      const [fruit, setFruit] = useState('Lemon')
      // 输入框输入的内容,以及输入框onChange的操作
      const [input, setInput] = useState('')
      // 水果列表
      const [fruits, setFruits] = useState(['apple', 'pear'])
    
      return (
          <div>
            <p>点击了{count}次</p>
            <button onClick={() => setCount(count + 1)}>点击</button>
    
            <p>选择的水果:{fruit}</p>
    
            <p>
              <input type="text" value={input} onChange={(e) => {setInput(e.target.value)}}></input>
              <button onClick={() => {setFruits([...fruits, input])}}>新增水果</button>
            </p>
    
            <ul>
              {/* 点击列表项,将列表项内容展示在上面的选择的水果。。。 */}
              {fruits.map(fruit => (<li key={fruit} onClick={() => setFruit(fruit)}>{fruit}</li>))}
            </ul>
          </div>
      )
    } 
    
    • 下面的例子,理解一个概念叫副作用钩子 - Effect Hook,可以将其理解为 componentDidMountcomponentDidUpdatecomponentWillUnmount 这几个生命周期的复合,可以理解为一个合成API;我们写一个功能当点击按钮记录点击次数时,同时修改浏览器当前标签页的标题,将标题也改为记录次数,如果我们用 class组件做这个功能,要在好几个生命周期内执行标题更新的逻辑,但是现在有了 Effect Hook 就方便多了,使用前要先引入 useEffect
    // src/components/HookTest.js
    import React, {useState, useEffect} from 'react';
    
    export default function HookTest () {
    
      // useState(initialState)是一个方法,该方法返回一个数组
      // 解构数组后第0项表示状态,我们初始化了这个状态值为0,第1项是更新状态值的方法 
      const [count, setCount] = useState(0)
    
      // 每次渲染时都执行
      // 可以理解为class类组件中的componentDidMount、componentDidUpdate、componentwillUnmount的合并api
      useEffect (() => {
        document.title =  `你点击了${count}次`
      })
    
      return (
          <div>
            <p>点击了{count}次</p>
            <button onClick={() => setCount(count + 1)}>点击</button>
          </div>
      )
    } 
    
    • 上面例子展示了 useEffect 每次渲染都会执行,那在有些情况下这明显是不合理的,比如需要在 useEffect 里调用api时,这里就需要给 useEffect 传递第二个参数,第二个参数是一个依赖数组,也就是可以有同时有多个依赖
    // src/components/HookTest.js
    import React, {useState, useEffect} from 'react';
    
    export default function HookTest () {
    
      // useState(initialState)是一个方法,该方法返回一个数组
      // 解构数组后第0项表示状态,我们初始化了这个状态值为0,第1项是更新状态值的方法 
      const [count, setCount] = useState(0)
    
      // 每次渲染时都执行
      // 可以理解为class类组件中的componentDidMount、componentDidUpdate、componentwillUnmount的合并api
      useEffect (() => {
        document.title =  `你点击了${count}次`
      })
    
      // useEffect会在每次组件都渲染时调用,那么如果需要在此方法内部调用api时,频繁调用api就不合理了
      // 这时可以给useEffect方法传递第二个参数,为[],表示没有任何依赖,只需要执行1次
      useEffect (() => {
        // ...api调用
        console.log('api调用')
      }, [])
    
      // useEffect还可以根据依赖决定自身是否每次渲染都调用,如果依赖没有变,那渲染也是没有意义的
      // 这时给useEffect方法传递第二个参数,传依赖,依赖count不变就不执行
      useEffect (() => {
        document.title =  `你点击了${count}次`
      }, [count])
    
      return (
          <div>
            <p>点击了{count}次</p>
            <button onClick={() => setCount(count + 1)}>点击</button>
          </div>
      )
    } 
    
    • 除了以上用法,Hook 中还有一个用法叫自定义钩子,他可以将某个 Hook 的逻辑抽离出来,以供多个组件复用,语法要求是以 use... 开头命名一个函数
    // src/components/HookTest.js
    import React, {useState, useEffect} from 'react';
    
    // 自定义hook是个函数,名称用use开头即可,函数内部可以调用其他hook
    function useAge () {
      const [age, setAge] = useState(0)
      useEffect(() => {
        setTimeout(() => {
          setAge(20)
        }, 2000)
      })
      return age;
    }
    
    export default function HookTest () {
      // 在需要使用的地方直接调用自定义钩子方法即可
      const age = useAge()
    
      return (
        <div>
          <p>年龄:{age ? age : 'loading...'}</p>
        </div>
      )
    }
    

    相关文章

      网友评论

          本文标题:React - Hook

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