美文网首页
React Hook 概述

React Hook 概述

作者: SingleDiego | 来源:发表于2020-09-10 15:59 被阅读0次

    官方文档:https://react.docschina.org/docs/hooks-intro.html




    Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。




    Hook 的作用位置

    复习一下, React 的函数组件是这样的:

    const Example = (props) => {
      // 你可以在这使用 Hook
      return <div />;
    }
    

    或是这样:

    function Example(props) {
      // 你可以在这使用 Hook
      return <div />;
    }
    

    Hook 的作用范围就在上诉的函数组件之内,之前我们可能把它们叫做“无状态组件”。但现在我们为它们引入了使用 React state 的能力,所以我们更喜欢叫它”函数组件”。

    Hookclass 内部是不起作用的。




    State Hook

    用一个计数器的简单例子来说明:

    import React, { useState } from 'react'
    import ReactDOM from 'react-dom'
    
    function Example() {
      // 相当于声明一个叫 “count” 的 state 变量
      // setCount 为设定变量 count 的函数
      // useState(0) 设定了 count 的默认值为 0
      // 注意:count,setCount 都是可以自定义命名的,并非 useState 自身的 API
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    ReactDOM.render(
      <Example />, 
      document.getElementById('root')
    )
    

    上述代码产生了一个简单的点击就 +1 的计数器组件。

    通过使用 useState 我们无需使用 class 就可以使用 state 的特性,如果要用 class 来实现上面操作,会是这样:

    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
    
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
        );
      }
    }
    
    声明多个 State Hook

    你可以在一个组件中多次使用 State Hook

    function ExampleWithManyStates() {
      // 声明多个 state 变量!
      const [age, setAge] = useState(42);
      const [fruit, setFruit] = useState('banana');
      const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
      // ...
    }
    
    带参数的函数

    下例中,我们可以通过参数来决定,数目增加的多数。

    function App() {
      const [count, setCount] = useState(0);
    
      const handalClick = (num) => () => {
        setCount(count + num)
      };
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={handalClick(10)}>
            + 10
          </button>
        </div>
      );
    }
    




    Effect Hook

    useEffect 是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMountcomponentDidUpdatecomponentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

    下面用一个例子演示,在组件挂载时和组件更新时,会更新 HTML 的 title

    import React, { useState, useEffect } from 'react'
    import ReactDOM from 'react-dom'
    
    function Example() {
      const [count, setCount] = useState(0);
    
      // 相当于 componentDidMount 和 componentDidUpdate:
      useEffect(() => {
        // 使用浏览器的 API 更新页面标题
        document.title = `You clicked ${count} times`;
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    ReactDOM.render(
      <Example />, 
      document.getElementById('root')
    )
    

    当你调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更改后运行你的 useEffect 里的函数。默认情况下,React 会在每次渲染后调用副作用函数 ,包括第一次渲染。

    由于副作用函数是在组件内声明的,所以它们可以访问到组件的 propsstate

    useEffect 函数还可以通过返回一个函数,来指定组件销毁阶段的操作。

    function Example() {
      const [count, setCount] = useState(0);
    
      // 相当于 componentDidMount 和 componentDidUpdate:
      useEffect(() => {
        // 使用浏览器的 API 更新页面标题
        document.title = `You clicked ${count} times`;
        // 这部分代码组件第一次渲染时不执行
        // 组件更新前的销毁阶段执行,相当于 componentWillUnmount
        return () => {
          console.log('组件销毁')
        };
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    通过跳过 Effect 进行性能优化
    function Example() {
      const [count1, setCount1] = useState(0);
      const [count2, setCount2] = useState(0);
    
      useEffect(() => {
        console.log(`You clicked button-1 ${count1} times`);
      }, [count1]); // 只有 count1 更新时才执行
    
      useEffect(() => {
        console.log(`You clicked button-2 ${count2} times`);
      }, [count2]);  // 只有 count2 更新时才执行
    
      return (
        <div>
          <p>You clicked button-1 {count1} times</p>
          <p>You clicked button-2 {count2} times</p>
    
          <button onClick={() => setCount1(count1 + 1)}>
            Click 1
          </button>
          <button onClick={() => setCount2(count2 + 1)}>
            Click 2
          </button>
        </div>
      );
    }
    

    上述代码演示了限制特定的 state 变化再触发 useEffect 函数的执行。

    如果 useEffect 的第二个参数为空数组,则该 useEffect 函数只在第一次渲染时候执行。

    useEffect(() => {
        console.log(`start`);
      }, []);  //只在第一次渲染时候执行
    

    相关文章

      网友评论

          本文标题:React Hook 概述

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