Introdução aos ganchos:
React Hooks é um recurso introduzido no React 16.8. É um conjunto de funções que permitem que você use os recursos do React em componentes de função, como gerenciamento de estado, tratamento de efeitos colaterais, etc. No React anterior, a reutilização de estado e lógica geralmente exigia o uso de componentes de classe e de ordem superior, enquanto os Hooks nos permitiam concluir essas tarefas em componentes de função, tornando o código mais conciso e fácil de entender.
A diferença entre Hooks e classes:
- Componentes baseados em classe: use classes para definir componentes e gerencie métodos de estado e ciclo de vida herdando React.Component.
- Hooks: Use funções para definir componentes, gerenciar estado e lidar com efeitos colaterais por meio de um conjunto de funções Hook específicas, tornando a lógica do componente mais independente e reutilizável.
Por que usar Ganchos:
O uso de Hooks pode trazer os seguintes benefícios:
- O código é mais conciso: em comparação com componentes de classe, Hooks torna a lógica dos componentes mais concentrada, tornando o código mais fácil de ler e manter.
- Reutilização de lógica: ao personalizar o Hook, você pode reutilizar melhor a lógica do componente e reduzir a redundância de código.
- Evite o aninhamento de inferno: Em componentes complexos, o aninhamento de inferno (callback hell) pode aparecer em componentes de classe, e os Hooks podem resolver melhor esse problema.
- Melhor otimização de desempenho: Hooks podem trazer melhor otimização de desempenho em alguns casos.
Agora vamos apresentar os Hooks um por um e dar exemplos de código e análise de anotação:
1. useState:
useState é o Gancho mais básico para adicionar estado em componentes de função.
import React, { useState } from 'react';
const Counter = () => {
// 定义状态count和更新函数setCount,并初始化count为0
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1); // 更新count的值
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
export default Counter;
Análise de comentários :
- Use o gancho
import { useState } from 'react';
de importaçãouseState
. - Usado dentro do componente
useState
, o valor de estado inicial 0 é passado e ele retorna um array contendo as funções de estado e atualização de estado.Aqui usamos a atribuição de desestruturação de array para atribuí-los acount
e respectivamentesetCount
. - No
onClick
evento do botão, chameincrement
a função que ele chamarásetCount
para atualizar o estadocount
.
2. useEffect:
useEffect é usado para executar operações de efeito colateral (como aquisição de dados , assinatura, operação DOM, etc.) em componentes de função, semelhante à combinação de e em componentDidMount
componentes de classe .componentDidUpdate
componentWillUnmount
import React, { useState, useEffect } from 'react';
const DataFetchExample = () => {
const [data, setData] = useState(null);
useEffect(() => {
// 模拟数据获取
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data))
.catch(error => console.error(error));
}, []); // 传入空数组,只在组件挂载和卸载时执行
return (
<div>
{data ? <p>{data}</p> : <p>Loading...</p>}
</div>
);
};
export default DataFetchExample;
Análise de comentários :
- Use o gancho
import { useEffect } from 'react';
de importaçãouseEffect
. - Usado dentro do componente
useEffect
, passe uma função callback e um array vazio (array de dependência).setData
A lógica de aquisição de dados é definida na função de retorno de chamada e o status de atualização é usado após a aquisição de dados ser bem-sucedida . - Como um array vazio é passado como dependência, isso
useEffect
só é executado quando o componente é montado e desmontado.
3. useContext:
useContext é usado para usar o contexto do React em componentes de função.
import React, { useContext } from 'react';
const UserContext = React.createContext();
const UserInfo = () => {
const user = useContext(UserContext);
return (
<div>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
);
};
const ParentComponent = () => {
const user = {
name: 'John Doe',
email: '[email protected]'
};
return (
<UserContext.Provider value={user}>
<UserInfo />
</UserContext.Provider>
);
};
export default ParentComponent;
Análise de comentários :
- Use o gancho
import { useContext } from 'react';
de importaçãouseContext
. - Use
React.createContext()
para criar um objeto Context eUserContext.Provider
fornecer dados por meio da árvore de componentes. UserInfo
Usado no componente parauseContext(UserContext)
obter os dados doUserContext.Provider
arquivouser
.
4. Use Redutor:
useReducer é usado para executar lógica de estado complexa em componentes de função.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<p>Count: {state.count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter;
Análise de comentários :
- Use o gancho
import { useReducer } from 'react';
de importaçãouseReducer
. - Uma função é definida
reducer
para processar a lógica de atualização do estado eaction.type
alterar o estado de acordo com ela. - Use
useReducer
o Hook para criar o estado edispatch
as funções correspondentes, semelhante a como o Redux é usado. - Na função
increment
edecrement
, a atualização de status é acionadadispatch
enviando um diferente, respectivamentetype
.
5. useCallback:
useCallback é usado para armazenar funções de retorno de chamada em cache em componentes de função para evitar a recriação desnecessária quando as dependências não mudam.
import React, { useState, useCallback } from 'react';
const Button = ({ onClick, label }) => {
console.log(`Button ${label} is rendered`);
return <button onClick={onClick}>{label}</button>;
};
const ParentComponent = () => {
const [count, setCount] = useState(0);
// 使用useCallback缓存increment函数
const increment = useCallback(() => {
setCount(count + 1);
}, [count]); // 依赖数组为[count]
return (
<div>
<p>Count: {count}</p>
<Button onClick={increment} label="Increment" />
</div>
);
};
export default ParentComponent;
Análise de comentários :
- Use o gancho
import { useCallback } from 'react';
de importaçãouseCallback
. ParentComponent
Um subcomponente é definido em ,Button
que recebeonClick
elabel
como props.- Use
useCallback
para armazenar em cacheincrement
a função e a matriz dependente é[count]
, o que significa quecount
ela será recriada somente quando houver uma alteraçãoincrement
.
6. Lembrete de uso:
useMemo é usado para armazenar resultados de cálculo em cache em componentes de função para evitar cálculos repetidos desnecessários.
import React, { useState, useMemo } from 'react';
const ExpensiveCalculation = ({ count }) => {
// 模拟一个昂贵的计算
const result = useMemo(() => {
console.log('Calculating...');
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]); // 依赖数组为[count]
return <p>Result: {result}</p>;
};
const ParentComponent = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<ExpensiveCalculation count={count} />
</div>
);
};
export default ParentComponent;
Análise de comentários :
- Use o gancho
import { useMemo } from 'react';
de importaçãouseMemo
. ExpensiveCalculation
UseuseMemo
o resultado do cálculo do cache no componente, e o array dependente serve para[count]
indicar quecount
será recalculado somente quando houver alteração.- Em
ParentComponent
um evento de clique de botão em ,count
o valor é atualizado, causando um recálculoExpensiveCalculation
no componente .useMemo