为了账号安全,请及时绑定邮箱和手机立即绑定

React Hooks 入门:让你的函数组件更强大简洁

简短介绍

React Hooks 是 React 中最重要的功能之一,使状态管理变得更简单,并让函数组件和类组件一样强大。它们解决了以前版本中的一些问题,并已经成为现代 React 开发的标准选择。

……

React Hooks

(React 钩子是一种新的 API,允许你在不编写 class 的情况下使用状态或其他 React 特性)

React Hook 是一些函数,让你可以在函数组件中使用 React 的特性(如状态和生命周期方法)。它们使代码更干净、更简洁、更易读,从而提升了可维护性。

此处略

为什么引入了钩子(hooks)?

React Hooks(React钩子)解决了类组件中遇到的几个问题:

  • 类的复杂性:
    在类组件中管理生命周期和状态往往容易出错,而 Hooks 让这变得更简单了。

  • 逻辑可重复使用性:
    Hooks 让逻辑可以在不同组件间重用,而不用 HOCs 或 render props。

  • 改进代码可读性:
    钩子功能使组件代码更简洁,让代码更易懂。

  • 渐进式采用:
    可以将钩子与类组件一起使用,逐步进行迁移。

——

React Hooks 准则

React 提供了几个钩子(hooks)。让我们通过示例和详细解释来逐一探索这些钩子。

……

1. 用于管理组件状态的 Hook (useState)

在功能组件中管理状态。

例子:

    import React, { useState } from 'react';

    const 计数器 = () => {
        const [count, setCount] = useState(0); // 初始化计数状态

        return (
            <div>
                <p>当前的计数是: {count}</p>
                <button onClick={() => setCount(count + 1)}>增加计数</button>
            </div>
        );
    }

    export default 计数器;

进入全屏 退出全屏

下面解释一下:

  • useState 将状态值设置为 0。

  • 设置计数来更新状态值。

……

2. useEffect(React.js 中用于副作用的钩子)

处理诸如获取数据或更新网页结构的副作用,如获取数据或更新 DOM。

例子:

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

    // function Timer(): 计时器组件,用于显示经过的时间
    function Timer() {
        // 定义一个状态变量,表示经过的时间
        const [time, setTime] = useState(0);

        // 在组件挂载时设置定时器,每秒更新一次时间
        useEffect(() => {
            const interval = setInterval(() => setTime(t => t + 1), 1000);
            // 在组件卸载时清理定时器
            return () => clearInterval(interval);
        }, []); // 仅在挂载时运行一次

        // 返回一个显示经过时间的DOM元素
        return <p>经过的时间: {time}s</p>;
    }

    export default Timer;

全屏模式,退出全屏

说明:

当组件由于空依赖数组 [] 加载时,效果会被执行一次。

  • 卸载时,清理间隔。

此处省略

3. 使用 useContext

查看上下文中的值。

例子:

    import React, { useContext, createContext } from 'react';

    const ThemeContext = createContext('light');

    function ThemedButton() {
        const theme = useContext(ThemeContext);

        return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>我是 {theme} 风格</button>;
    }

    function App() {
        return (
            <ThemeContext.Provider value="dark">
                <ThemedButton />
            </ThemeContext.Provider>
        );
    }

    export default App;

进入全屏 退出全屏

解释一下:

从最近的 ThemeContext.Provider 中取值,这是 useContext 的功能。

4. 使用 useReducer

处理复杂的状态。

例子:

    import React, { useReducer } from 'react';

    const initialState = { count: 0 };

    function reducer(state, action) {
        switch (action.type) {
            case 'increment':
                return { count: state.count + 1 };
            case 'decrement':
                return { count: state.count - 1 };
            default:
                throw new Error('未知的操作类型');
        }
    }

    function 计数器组件() {
        const [state, dispatch] = useReducer(reducer, initialState);

        return (
            <div>
                <p>当前计数: {state.count}</p>
                <button onClick={() => dispatch({ type: 'increment' })}>加</button>
                <button onClick={() => dispatch({ type: 'decrement' })}>减</button>
            </div>
        );
    }

    export default 计数器组件;

全屏 退出全屏

解释如下:

  • useReducer 可以通过操作来管理复杂的状态变化。

    • *

5. useRef(一个Hooks,用于在函数组件中保存可变值)

保存值或DOM节点。

例子:

    import React, { useRef } from 'react';

    function FocusInput() {
        const inputRef = useRef();

        const focus = () => inputRef.current.focus();

        return (
            <div>
                <input ref={inputRef} placeholder="点击按钮聚焦" />
                <button onClick={focus}>点击聚焦</button>
            </div>
        );
    }

    export default FocusInput;

全屏,退出全屏

解释:

这个 ref 会一直存在,并且在每次渲染时都指向 DOM 元素。


6. useMemo (记忆化处理)

记忆化昂贵的计算过程。

例子:

    import React, { useMemo } from 'react';

    function Factorial({ number }) {
        const factorial = useMemo(() => {
            const calculateFactorial = n => (n <= 1 ? 1 : n * calculateFactorial(n - 1));
            return calculateFactorial(number);
        }, [number]);

        return <p>数字 {number} 的阶乘是 {factorial}</p>;
    }

    export default Factorial;

进入全屏 退出全屏

说明:

  • useMemo 避免在 number 变化时重新计算“阶乘”。

    • *

7. 使用 useCallback 函数

为一个函数添加缓存结果。

例子:

import React, { useState, useCallback } from 'react';

function 计数器() {
    const [count, setCount] = useState(0);

    const increment = useCallback(() => setCount(prev => prev + 1), []);

    return (
        <div>
            <p>计数器: {count}</p>
            <button onClick={increment}>递增</button>
        </div>
    );
}

export default 计数器;

全屏模式,退出全屏

解释:
避免在重新渲染时不必要的增量重建。


8. 使用布局效应 (类似于useEffect,但用于布局计算)

在 DOM 变动前同步执行。

例子:

    import React, { useState, useLayoutEffect, useRef } from 'react';

    function Box() {
        const boxRef = useRef();
        const [color, setColor] = useState('蓝');

        useLayoutEffect(() => {
            console.log('输出:\'Box 尺寸:\'', boxRef.current.getBoundingClientRect());
        }, [color]);

        return (
            <div>
                <div ref={boxRef} style={{ width: 100, height: 100, background: color }}></div>
                <button onClick={() => setColor(color === '蓝' ? '红' : '蓝')}>换色</button>
            </div>
        );
    }

    export default Box;

全屏模式 退出全屏

解释:

  • useLayoutEffect 确保在在浏览器绘制之前 DOM 测量。

(Note: After reviewing the sentence, it seems there is a slight redundancy in the phrase "确保在在浏览器绘制之前", it should be corrected to "确保在浏览器绘制之前". Thus, the corrected translation is:)

  • useLayoutEffect 确保在浏览器绘制之前 DOM 测量。

    • *
结论如下

React Hooks 让组件逻辑更简洁,提高代码的重用性,从而提高开发效率。理解并有效运用 Hooks,你可以编写更干净、更高效且性能更佳的 React 应用。

掌握这些钩子后,你就能完全发挥 React 框架的全部潜能!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消