react 常用的hooks
-
import React, { useState } from 'react'; const Counter = () => { const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); };
-
useEffect
:用于在函数组件中执行副作用操作,比如订阅/取消订阅、数据获取等。import React, { useEffect, useState } from 'react'; const DataFetcher = () => { const [data, setData] = useState(null); useEffect(() => { // 在组件挂载后执行副作用操作 fetchData().then((result) => { setData(result); }); // 在组件卸载前执行清理操作 return () => { cleanup(); }; }, []); return <div>{data ? <p>Data: {data}</p> : <p>Loading...</p>}</div>; };
-
useContext
:用于在函数组件中访问和使用上下文(Context)。import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); const ThemeComponent = () => { const theme = useContext(ThemeContext); return <div>Current theme: {theme}</div>; };
-
useReducer
:用于在函数组件中管理复杂的状态逻辑。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: throw new Error('Unknown action type'); } }; 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> ); };
-
useCallback
:用于在函数组件中缓存回调函数,以避免不必要的重新创建。import React, { useState, useCallback } from 'react'; const Counter = () => { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(count + 1); }, [count]); return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); };
-
useMemo
:用于在函数组件中缓存计算结果,以避免不必要的重复计算。import React, { useMemo } from 'react'; const ExpensiveCalculation = ({ a, b }) => { const result = useMemo(() => { // 进行昂贵的计算 return a + b; }, [a, b]); return <div>Result: {result}</div>; };
-
useRef
:用于在函数组件中创建可变的引用,以存储和访问DOM元素或其他值。import React, { useRef } from 'react'; const FocusableInput = () => { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus Input</button> </div> ); };
除了上述提到的常用Hooks(useState
、useEffect
、useContext
、useReducer
、useCallback
、useMemo、useRef
)之外,React还提供了一些其他的Hooks,用于处理不同的场景和需求。以下是其他的React Hooks:
8.useLayoutEffect
:类似于useEffect
,但在DOM更新之后同步触发,用于执行需要读取DOM布局信息的副作用操作。
import React, { useLayoutEffect, useState } from 'react'; const ElementSize = () => { const [width, setWidth] = useState(0); useLayoutEffect(() => { const updateWidth = () => { setWidth(elementRef.current.offsetWidth); }; window.addEventListener('resize', updateWidth); updateWidth(); return () => { window.removeEventListener('resize', updateWidth); }; }, []); return <div ref={elementRef}>Width: {width}px</div>; };
9.useImperativeHandle
:用于在自定义Hooks中向父组件暴露特定的实例值或函数。
import React, { useImperativeHandle, forwardRef } from 'react'; const CustomInput = forwardRef((props, ref) => { const inputRef = useRef(null); useImperativeHandle(ref, () => ({ focusInput: () => { inputRef.current.focus(); }, // 其他暴露给父组件的方法或值 })); return <input ref={inputRef} type="text" />; }); // 在父组件中使用 const ParentComponent = () => { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focusInput(); }; return ( <div> <CustomInput ref={inputRef} /> <button onClick={focusInput}>Focus Input</button> </div> ); };
了解了基本的hooks 后我们在项目中常常需要自定义hooks来处理一些复杂的场景,用于处理网络请求的Hooks,使得在函数组件中进行数据获取和处理变得更加方便。以下是两个常用的用于处理网络请求的React Hooks:
-
import React, { useState, useEffect } from 'react'; const DataFetcher = () => { const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await fetch('https://api.example.com/data'); const result = await response.json(); setData(result); } catch (error) { console.error('Error fetching data:', error); } }; fetchData(); }, []); return ( <div> {data ? ( <ul> {data.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> ) : ( <p>Loading...</p> )} </div> ); };
useEffect
:useEffect
是一个非常常用的Hook,可以用于在组件渲染后执行副作用操作,例如发起网络请求。你可以在useEffect
中使用fetch
、axios
或其他类似的库来进行数据获取,并在获取到数据后更新组件的状态。
上述示例中,我们使用fetch
函数从https://api.example.com/data
获取数据,并将结果存储在组件的状态中。在组件渲染后,useEffect
会执行副作用操作,即发起网络请求,并在获取数据后更新组件的状态。
2.自定义的数据获取Hooks:除了使用useEffect
进行网络请求,你还可以创建自定义的Hooks,专门用于处理数据获取逻辑。这可以使你的代码更加模块化和可重用。
import React, { useState, useEffect } from 'react'; const useDataFetcher = (url) => { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { setIsLoading(true); try { const response = await fetch(url); const result = await response.json(); setData(result); } catch (error) { setError(error); } setIsLoading(false); }; fetchData(); }, [url]); return { data, isLoading, error }; }; const DataFetcher = () => { const { data, isLoading, error } = useDataFetcher('https://api.example.com/data'); return ( <div> {isLoading ? ( <p>Loading...</p> ) : error ? ( <p>Error: {error.message}</p> ) : ( <ul> {data.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> )} </div> ); };
上面主要是对useState ,useEffect的常用场景,我们接下来看下我们如果处理表格的内容时候的使用场景,处理表格的Hooks可以根据具体的需求和功能,使用多个不同的Hooks来实现。下面是几个常用的Hooks,可用于处理表格相关的功能:
1.useState
:useState
是React提供的基础Hook,用于在组件中管理状态。你可以使用useState
来存储和更新表格的数据。
import React, { useState } from 'react'; const Table = () => { const [data, setData] = useState([ { id: 1, name: 'John', age: 25 }, { id: 2, name: 'Jane', age: 30 }, // 其他表格数据 ]); return ( <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> {data.map((row) => ( <tr key={row.id}> <td>{row.id}</td> <td>{row.name}</td> <td>{row.age}</td> </tr> ))} </tbody> </table> ); };
2.useMemo
:useMemo
可以在函数组件中缓存计算结果,以避免不必要的重复计算。在表格中,你可以使用useMemo
来计算和缓存派生数据,例如根据表格数据计算某一列的总和或平均值。
import React, { useState, useMemo } from 'react'; const Table = () => { const [data, setData] = useState([...]); const totalAge = useMemo(() => { return data.reduce((sum, row) => sum + row.age, 0); }, [data]); return ( <div> <table> {/* 表格渲染 */} </table> <p>Total Age: {totalAge}</p> </div> ); };
3.useSort
:自定义的用于处理表格排序的Hook。该Hook可以用来管理表格中的排序状态,并根据点击表头进行排序。
import React, { useState } from 'react'; const useSort = (initialData, sortKey = null, sortOrder = 'asc') => { const [data, setData] = useState(initialData); const [key, setKey] = useState(sortKey); const [order, setOrder] = useState(sortOrder); const handleSort = (newKey) => { if (newKey === key) { setOrder(order === 'asc' ? 'desc' : 'asc'); } else { setKey(newKey); setOrder('asc'); } }; // 根据排序状态对数据进行排序 const sortedData = useMemo(() => { if (!key) { return data; } const sorted = [...data].sort((a, b) => { if (a[key] < b[key]) return order === 'asc' ? -1 : 1; if (a[key] > b[key]) return order === 'asc' ? 1 : -1; return 0; }); return sorted; }, [data, key, order]); return { data: sortedData, handleSort }; }; const Table = () => { const { data, handleSort } = useSort([...]); return ( <table> <thead> <tr> <th onClick={() => handleSort('id')}>ID</th> <th onClick={() => handleSort('name')}>Name</th> <th onClick={() => handleSort('age')}>Age</th> </tr> </thead> <tbody> {data.map((row) => ( <tr key={row.id}> <td>{row.id}</td> <td>{row.name}</td> <td>{row.age}</td> </tr> ))} </tbody> </table> ); };
对于react中我们绑定的点击事件有几种方法呢?
1.,你可以使用onClick
属性来绑定点击事件。这个属性接收一个函数,当元素被点击时,该函数会被调用。
import React from 'react'; const Button = () => { const handleClick = () => { console.log('Button clicked!'); }; return ( <button onClick={handleClick}>Click me</button> ); };
2.你也可以直接在onClick
属性中定义一个匿名函数,如下所示
import React from 'react'; const Button = () => { return ( <button onClick={() => console.log('Button clicked!')}>Click me</button> ); };
如果你需要将参数传递给点击事件处理函数,有几种方式可以实现:
1.使用箭头函数: 可以在事件处理函数中使用箭头函数来传递参数。在箭头函数中调用你的事件处理函数,并将参数传递给它。
import React from 'react'; const Button = () => { const handleClick = (param) => { console.log('Button clicked with param:', param); }; return ( <button onClick={() => handleClick('Hello')}>Click me</button> ); }; ```
在上面的例子中,我们使用箭头函数将参数`'Hello'`传递给`handleClick`函数。
2.使用.bind()
方法:你可以使用.bind()
方法来绑定参数到事件处理函数。
import React from 'react'; const Button = () => { const handleClick = (param) => { console.log('Button clicked with param:', param); }; return ( <button onClick={handleClick.bind(null, 'Hello')}>Click me</button> ); }; ```
在上面的例子中,我们使用`.bind()`方法将参数`'Hello'`绑定到`handleClick`函数。
还可以使用闭包来传递参数(很少用)
import React from 'react'; const Button = () => { const handleClick = (param) => { return () => { console.log('Button clicked with param:', param); }; }; return ( <button onClick={handleClick('Hello')}>Click me</button> ); };