世界杯预选赛中国队赛程_世界杯多少年一次 - fybstd.com


一、回顾一下Hooks的概念

Hooks 是 React 16.8 版本引入的新特性,它可以让你在函数组件中使用 state 以及其他 React 特性。在此之前,只有 class 组件才能使用这些功能。Hooks 的引入,使得我们可以在不使用类的情况下构建 React 应用程序。

二、 Hooks 解决了什么问题

组件复用状态逻辑的问题

之前,我们通常会在生命周期函数中编写代码逻辑,而生命周期函数难以进行复用。Hooks 则可以把这些逻辑抽离到一个可复用的函数中。

大型组件难以理解

React 组件越来越大,代码逻辑就会变得难以理解和维护。Hooks 通过将相关逻辑分割到更小的函数中,使代码更加清晰易懂。

难以理解的 class

对于一些开发人员来说,在 JavaScript 中理解 class 并不是一件容易的事情。Hooks 完全使用函数,让开发人员更容易理解React组件。

三、常见的Hooks有哪些

useState:用于声明状态变量useEffect:用于处理组件的副作用useContext:用于订阅 React 上下文useReducer:用于管理组件状态useCallback:用于缓存函数useMemo:用于缓存计算结果useRef:用于创建可变的 ref 对象useImperativeHandle:用于自定义暴露给父组件的实例值useLayoutEffect:与 useEffect 相同,但是会在所有DOM改变之后同步触发useDebugValue:用于在 React 开发工具中显示自定义 hook 的标签

总的来说,Hooks 让我们在函数组件中也能使用 state 以及其他 React 特性,提高了组件逻辑复用性,同时使代码更加清晰易懂。

四、10种核心Hooks用法和使用场景

useState

import React, { useState } from 'react';

function Example() {

const [count, setCount] = useState(0); // 声明状态变量及其setter函数

return (

You clicked {count} times

);

}

使用场景: 在函数组件中管理状态,如计数器、表单控件等。注意事项:

useState只接受一个参数作为初始状态状态更新会引起组件重新渲染,因此避免在主体渲染中调用setState可以使用多个useState管理不同状态

useEffect

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

function Example() {

const [data, setData] = useState([]);

useEffect(() => {

// 模拟网络请求

const fetchData = setTimeout(() => {

setData([1, 2, 3]);

}, 2000);

// 清理副作用

return () => clearTimeout(fetchData);

}, []); // 空数组确保只运行一次

return

    {data.map(item =>
  • {item}
  • )}
;

}

使用场景: 执行有副作用的操作,如发送网络请求、订阅事件等。注意事项:

第二个参数是一个数组,用于指定effect的依赖项,只有依赖项变化时才会重新执行返回一个清理函数,用于清理副作用,如取消订阅等空数组[]表示只在组件挂载和卸载时执行

useContext

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

const ThemeContext = createContext('light');

function App() {

return (

);

}

function Toolbar() {

return (

);

}

function ThemedButton() {

const theme = useContext(ThemeContext);

return ;

}

使用场景: 跨层级组件传递数据,避免手动逐层传递 props。注意事项:

需要先使用createContext创建Context对象上层组件使用Provider提供数据下层组件使用useContext获取数据

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 Counter() {

const [state, dispatch] = useReducer(reducer, initialState);

return (

<>

Count: {state.count}

);

}

使用场景: 状态逻辑较复杂时,可以使用 Reducer 模式优化状态管理。注意事项:

useReducer接收两个参数,第一个是reducer函数,第二个是初始状态reducer函数根据不同的action决定如何更新状态dispatch用于发送action从而更新状态

useCallback

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

function Parent() {

const [count, setCount] = useState(0);

const [name, setName] = useState('');

const handleClick = useCallback(() => {

setCount(count + 1);

}, [count]);

return (

setName(e.target.value)} />

Count: {count}

);

}

const Child = React.memo(({ handleClick }) => {

console.log('Child rendered');

return ;

});

使用场景: 缓存函数实例,避免组件重新渲染时重复创建函数实例。注意事项:

第二个参数是一个数组,用于指定依赖项,只有依赖项变化时才会重新创建函数实例通常与React.memo或shouldComponentUpdate一起使用,提高性能

useMemo

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

function App() {

const [count, setCount] = useState(0);

const [name, setName] = useState('');

const data = useMemo(() => {

return { count, name };

}, [count, name]);

return (

Count: {count}

setName(e.target.value)} />

);

}

function Display({ data }) {

return

{JSON.stringify(data, null, 2)}
;

}

使用场景: 缓存计算结果,避免重复计算。注意事项:

第二个参数是一个数组,用于指定依赖项,只有依赖项变化时才会重新计算如果计算量非常小,使用可能引起额外开销,适合使用在计算量较大的场景

useRef

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

function App() {

const inputRef = useRef(null);

useEffect(() => {

inputRef.current.focus();

}, []);

return (

);

}

使用场景: 获取DOM元素或保存可变值的引用。注意事项:

useRef返回一个可变的ref对象,其current属性被初始化为传入的参数ref对象在组件的整个生命周期内保持不变

useImperativeHandle

import React, { useRef, forwardRef, useImperativeHandle } from 'react';

const Input = forwardRef((props, ref) => {

const inputRef = useRef();

useImperativeHandle(ref, () => ({

focus: () => {

inputRef.current.focus();

},

}));

return ;

});

const App = () => {

const inputRef = useRef();

const focusInput = () => {

inputRef.current.focus();

};

return (

);

};

使用场景: 使父组件可以获取子组件实例的句柄,调用子组件的方法。注意事项:

需要配合forwardRef来使用父组件通过ref获取子组件实例,子组件通过useImperativeHandle定义暴露给父组件的方法

useLayoutEffect

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

function App() {

const [value, setValue] = useState(0);

useLayoutEffect(() => {

if (value === 0) {

setValue(10 + Math.random() * 200);

}

}, [value]);

console.log('render', value);

return (

setValue(0)}>

Value: {value}

);

}

使用场景: 在DOM更新后立即执行一些同步操作,例如获取DOM元素位置等。注意事项:

与useEffect的执行时机不同,useLayoutEffect会在所有DOM变更之后同步执行

-如果操作非常昂贵,应该考虑使用useEffect以免阻塞浏览器渲染

useDebugValue

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

function useCustomHook(initialValue) {

const [value, setValue] = useState(initialValue);

useDebugValue(`Current value: ${value}`);

return [value, setValue];

}

function App() {

const [value, setValue] = useCustomHook(0);

return (

Value: {value}

);

}

使用场景: 在 React 开发者工具中显示自定义 Hook 的标签,方便调试。注意事项:

只在开发环境下有效,生产环境会被自动忽略第一个参数是一个格式化的字符串,用于显示标签内容

以上是一些常用 Hooks 的示例代码、使用场景和注意事项。在实际开发中,应根据具体需求合理选择和组合使用 Hooks,以提高代码的可读性和可维护性。同时也要注意 Hooks 的使用规则和限制,避免出现潜在的问题。