ReactJS钩子教程:useState,useEffect和useContext

作者 : IT 大叔 本文共5669个字,预计阅读时间需要15分钟 发布时间: 2020-11-6

能以前只能使用类来实现。这使我们可以编写更简洁,因此更易读的代码。

在本教程中,我们将学习如何使用三个主要的钩子:useStateuseEffectuseContext

useState

UseState是允许我们将状态添加到使用函数创建的组件的挂钩。

要查看此钩子如何工作,让我们创建一个计数器。

首先,让我们创建组件的基本结构:

import React from "react";

function Counter() {
   return (
      <div>
        <button>Contar</button>
        <p>0</p>
      </div>
   );
}


export default Counter;

现在导入useState挂钩:

import React, {useState} from "react";

最后,让我们为组件创建一个状态:

const [counter, setConter] = useState(0);

说明:

使用解构,我们将零值分配给我们的“计数器”状态,并将“ setCounter”函数分配给我们用于更改状态值的函数。

完成后,我们只需要在“ button”元素中分配更改状态的函数并使“ p”元素显示状态值,即:

<button onClick={() => setConter(counter + 1)}>Contar</button>
<p>{counter}</p>

最后,我们将有以下代码:

import React, { useState } from "react";
   function Counter() {
      const [counter, setConter] = useState(0);

      return (
         <div>
            <button
              onClick={() => setConter(counter + 1)}>
           Contar
        </button>
        <p>{counter}</p>
         </div>
      );
}

export default Counter;

在屏幕上,我们将得到:
ReactJS钩子教程:useState,useEffect和useContext插图

注意:与类状态一样,只要更改状态,组件都将再次呈现。

useEffect

如果您已经熟悉使用类来创建组件,则可以将useEffect挂钩与生命周期方法(componentDidMount(),componentWillUnmount()和componentWillUpdate())进行比较,尽管它们的工作方式有所不同。

UseEffect具有两个参数:函数和依赖项数组。看:

useEffect(() => {}, [])

UseEffect在以下三种情况之一中存储传递的函数以执行该函数:每当依赖项数组的元素被更新,呈现组件之后或卸载组件之后。

每当依赖项数组的元素更新时运行

要在依赖项数组的元素更新时执行该功能,只需将该元素添加到依赖项数组即可。

useEffect(() => {}, [elemento])

作为一个示例,让我们重用useState示例。我们将根据状态计数器的值更新页面的标题。

首先我们需要导入useEffect:

import React, { useState, useEffect } from "react";

现在,让我们创建将更改页面标题并将状态计数器添加到依赖项数组的函数:

useEffect(() => {
    document.title = `${counter} cliks`;
}, [counter]);

最后,我们的代码将是:

import React, { useState, useEffect } from "react";
function Counter() {
    const [counter, setConter] = useState(0);

    useEffect(() => {
        document.title = `${counter} cliks`;
    }, [counter]);

    return (
        <div>
                <button onClick={() => setConter(counter + 1)}>Contar</button>
        </div>
    );
}
export default Counter;

屏幕上的结果将是:

ReactJS钩子教程:useState,useEffect和useContext插图(2)

渲染组件后运行

要在渲染组件后(仅一次)执行该功能,只需将依赖项数组留空。

useEffect(() => {}, [])

为了举例说明,让我们创建一个名为Text的组件,然后在三秒钟后对其进行渲染。在屏幕上安装后,我们页面的标题将更改。

首先,让我们通过将两个参数传递给useEffect来创建Text组件。第一个函数将更改页面标题,第二个函数将更改为空数组。

function Text() {
    useEffect(() => {
        document.title = "O componente foi montado";
    }, []);

    return <p>O contador está visível!</p>;
}

现在,通过添加“可见”状态(默认值为false)和setTimeout函数来重新创建我们的Counter组件,该函数将在3秒后更改状态值:

const [visible, setVisible] = useState(false);

setTimeout(() => {
   setVisible(true);
}, 3000);

最后,仅当“可见”状态的值为true时,才渲染Text组件:

return <div>{visible ? <Text /> : ""}</div>;

最终代码将是:

import React, { useEffect, useState } from "react";


function Counter() {
    const [visible, setVisible] = useState(false);
    setTimeout(() => {
        setVisible(true);
    }, 3000);
    return <div>{visible ? <Text /> : ""}</div>;
}


function Text() {
    useEffect(() => {
        document.title = "O componente foi montado";
        }, []);
    return <p>O contador está visível!</p>;
}

export default Counter;

并在屏幕上显示结果:
ReactJS钩子教程:useState,useEffect和useContext插图(4)

卸载组件后运行

要在分解组件后执行该函数,只需返回一个函数:

useEffect(() => {
    return () => {}
}, [])

为了举例说明,让我们做与上一个示例相反的操作。这次,我们将在拆卸组件时更改页面标题。

为此,我们将保留前面示例的结构,仅对我们的代码进行三处更改。

首先,让我们将“可见”状态的值从false更改为true:

const [visible, setVisible] = useState(true);

其次,在setTimeout函数中,我们将setVisible中传递的值从true更改为false:

setTimeout(() => {
    setVisible(false);
}, 3000);

第三,我们将在useEffect中返回一个更改页面标题的函数:

useEffect(() => {
    document.title = "O componente foi montado";
    return () => {
        document.title = "O componente foi desmontado";
    };
})

最后,我们将有以下代码:

import React, { useEffect, useState } from "react";

function Counter() {
    const [visible, setVisible] = useState(true);    
    setTimeout(() => {
        setVisible(false);
    }, 3000);

    return <div>{visible ? <Text /> : ""}</div>;
}

function Text() {
    useEffect(() => {
        document.title = "O componente foi montado";
        return () => {
            document.title = "O componente foi desmontado";
        };
    }, []);

    return <p>O contador está visível!</p>;
}

export default Counter;

在屏幕上:

ReactJS钩子教程:useState,useEffect和useContext插图(6)

useContext

该挂钩旨在允许组件之间的数据共享。

为了说明该钩子的用法,我们将创建两个不同的组件。一种是增加计数器,另一种是显示计数器值。另外,我们将创建一个名为“ Context.js”的文件,该文件将负责共享计数器值:

创建Context.js文件

创建Context.js文件后,进行以下导入:

import React, { useState } from "react";

现在创建上下文:

const ConunterContext = React.createContext();

最后,创建将提供数据的组件并导出“ ConunterContext”:

export function Context(props) {
    const [counter, setCounter] = useState(0);
    return (
        <ConunterContext.Provider value={{ counter, setCounter }}>
            {props.children}
        </ConunterContext.Provider>
    );
}

export default ConunterContext;

说明:使用“上下文”组件,您将允许/提供数据,使用“ ConunterContext”,您将搜索数据。

允许数据访问

在App.js文件中,导入“上下文”并将“计数器”组件放在“上下文”提供程序内:

import React from "react";
import Counter from "./Components/Counter";
import { Context } from "./Components/Context";

function App() {
    return (
        <div className="App">
            <Context>
                <Counter />
            </Context>
        </div>
    );
}

export default App;

创建Text.js文件

导入“ useContext”和“ ConunterContext”:

import React, { useContext } from "react";
import ConunterContext from "./Context";

创建Text组件并使用解构来查找必要的数据,在这种情况下为计数器:

function Text() {
    const { counter } = useContext(ConunterContext);
    return (
        <div>
            <p>{counter}</p>
        </div>
    );
}

export default Text;

创建Counter.js文件

进行以下导入:

import React, { useContext } from "react";
import ConunterContext from "./Context";
import Text from "./Text";

创建Counter组件并访问必要的数据,在这种情况下为counter和setCounter:

function Counter() {
    const { setCounter, counter } = useContext(ConunterContext);
    return (
        <div>
            <button onClick={() => setCounter(counter + 1)}>Contar</button>
            <Text />
        </div>
    );
}

export default Counter;

最后,我们将拥有以下文件:

Context.js:

import React, { useState } from "react";

const ConunterContext = React.createContext();

export function Context(props) {
    const [counter, setCounter] = useState(0);    
    return (
        <ConunterContext.Provider value={{ counter, setCounter }}>
            {props.children}
        </ConunterContext.Provider>
    );
}

export default ConunterContext;

App.js:

import React from "react";
import Counter from "./Components/Counter";
import { Context } from "./Components/Context";

function App() {
    return (
        <div className="App">
            <Context>
                <Counter />
            </Context>
        </div>
    );
}

export default App;

Text.js:

import React, { useContext } from "react";
import ConunterContext from "./Context";

function Text() {
    const { counter } = useContext(ConunterContext);

    return (
        <div>
            <p>{counter}</p>
        </div>
    );
}

export default Text;

Counter.js:

import React, { useContext } from "react";
import ConunterContext from "./Context";
import Text from "./Text";

function Counter() {
    const { setCounter, counter } = useContext(ConunterContext);

    return (
        <div>
            <button onClick={() => setCounter(counter + 1)}>Contar</button>
            <Text />
        </div>
    );
}

export default Counter;

就是这样,我希望我能帮助您更好地理解这三个重要的钩子:)

免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » ReactJS钩子教程:useState,useEffect和useContext

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论