看看react中的hooks都有点啥
useState
用于在函数式组件中添加状态管理
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
function handleIncrement() {
setCount(oldCount => oldCount + 1);
}
function handleDecrement() {
setCount(oldCount => oldCount - 1);
}
return (
<div>
<h2>Counter: {count}</h2>
<button onClick={handleIncrement}>Increment</button>
<button onClick={handleDecrement}>Decrement</button>
</div>
);
}
useEffect
用于在函数式组件中添加副作用,比如发送网络请求,订阅事件等
import React, { useState, useEffect } from 'react';
function fetchData() {
// 发送网络请求获取数据
return fetch('https://someapi.com/data')
.then(response => response.json())
.then(data => data);
}
function DataDisplay() {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(data => setData(data));
}, []);
if (data === null) {
return <div>Loading...</div>;
}
return <div>{JSON.stringify(data)}</div>;
}
useContext
用于在函数式组件中使用全局数据
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme }}>I am styled by theme context!</button>;
}
import React, { useContext } from 'react'
import UserContext from './context';
function Demo() {
// 如果React.createContext没有指定默认值,也可以在对应子组件上套上UserContext.Provider来指定值
return (
// <UserContext.Provider value={{ name: '张三' }}>
<Child />
// </UserContext.Provider>
)
}
function Child() {
const UserContext = React.createContext( { name: '张三' });
const user = useContext(UserContext);
return (
<div>
<p>{`name: ${user.name}`}</p>
</div>
)
}
export default Demo;
**
useReducer
用于在函数式组件中使用复杂的状态逻辑,可以用于替代 useState
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() {
// 第一个参数reducer是一个函数,第二个参数initialState是定义state初始值
const [state, dispatch] = useReducer(reducer, initialState);
function handleIncrement() {
dispatch({ type: 'increment' });
}
function handleDecrement() {
dispatch({ type: 'decrement' });
}
return (
<div>
<h2>Counter: {state.count}</h2>
<button onClick={handleIncrement}>Increment</button>
<button onClick={handleDecrement}>Decrement</button>
</div>
);
}
useMemo
用于缓存计算结果,当计算结果不变时,可以避免重复计算
import React, { useState, useMemo } from 'react';
function fibonacci(n) {
if (n <= 1) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
function MyComponent({ number }) {
const result = useMemo(() => fibonacci(number), [number]);
return <div>{result}</div>;
}
在这个示例中,我们定义了一个计算斐波那契数列的函数 fibonacci
,然后使用 useMemo
缓存计算结果,只有当 number
发生变化时,才会重新计算。这样可以提高组件的性能。
useCallback
用于缓存函数,减少函数的重新创建
import React, { useState, useCallback } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const handleIncrement = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={handleIncrement}>Increment</button>
</div>
);
}
import { useState, useCallback } from 'react'
function Demo() {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
const funcHang = useCallback(function() {
console.log("function run:", count1, count2);
}, [count1]);
return (
<div>
<h2>params: { count1 } { count2 }</h2>
<button onClick={ funcHang }>触发</button>
<button onClick={ e => { setCount1(pre => pre + 1);} }>update Count1</button>
<button onClick={ e => { setCount2(pre => pre + 1);} }>update Count2</button>
</div>
)
}
export default Demo;
在这个示例中,我们使用 useCallback
缓存了一个叫做 handleIncrement
的函数,这个函数只有在 count
发生改变时才会重新创建。这样可以减少函数的重新创建,提高组件性能。
useRef
创建一个可变的 ref 对象,在 React 更新视图时不会重新渲染,可以用于保存和读取 DOM 元素、记录变量值等
import React, { useRef } from 'react';
function TextInput() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={handleClick}>Focus</button>
</div>
);
}
import { useRef } from 'react'
function Demo() {
const inputRef = useRef();
const handleFocus = () => {
// document.getElementById('my-input').focus();
inputRef.current.value = 'focus';
inputRef.current.focus();
}
const handleBlur = () => {
// document.getElementById('my-input').blur();
inputRef.current.value = 'blur';
inputRef.current.blur();
}
return (
<div>
<input ref={inputRef} id="my-input" />
<button onClick={handleFocus}>focus</button>
<button onClick={handleBlur}>blur</button>
</div>
)
}
export default Demo;
在这个示例中,我们使用 useRef
创建了一个 inputRef
对象,它可以用来保存 input 元素的引用。然后我们又定义了一个 handleClick
函数,当点击按钮时,调用 inputRef.current.focus()
来使 input 元素获得焦点。
useLocation
useLocation
是React Router
提供的一个Hooks,用于在React组件中获取当前页面URL地址的信息,包括pathname
、search
和hash
,从而可以在页面跳转、渲染和传递参数等方面进行更精细的控制。useLocation
的实现基于window.location
对象,所以在浏览器上运行的React应用程序才能使用它。在使用useLocation
时,需要先通过react-router-dom
引入它,然后在函数组件中通过调用useLocation
就可以获取到当前页面的URL地址信息。
import { useLocation } from 'react-router-dom'
const GeekLayout = () => {
const location = useLocation()
// 这里是当前浏览器上的路径地址
const selectedKey = location.pathname
return ( <div></div> )
}
forwardRef
forwardRef是一种高阶组件,用于将ref向下传递到子组件中。具体用法如下:
import React, { forwardRef, useRef } from 'react';
const Input = forwardRef((props, ref) => {
return <input type="text" ref={ref} {...props} />;
});
function App() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<Input ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
在上面的示例中,我们创建了一个名为Input
的组件,并使用forwardRef
将其转发给子组件,并将ref传递给子组件的input元素。在App
组件中,我们创建了一个ref,并将其传递给Input
组件。然后我们在App
组件中创建了一个按钮,并在点击时让input元素获得焦点,这是通过调用inputRef.current.focus()
实现的。这个功能是通过Props传递实现的,但是直接把ref传递给Input的话,Input组件是无法获得ref的,这时就可以使用forwardRef传递ref。
需要注意:
- forwardRef只能转发refs而不能转发其他props
- forwardRef要使用回调形式传递ref
转载自:https://juejin.cn/post/7226925675050483767