一、State Hook
const [age, setAge] = useState(42);
二、Effect Hook
useEffect
给函数组件增加了操作副作用的能力,跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。
useEffect(() => {
document.title = `You clicked ${count} times`;
});
还可以通过返回一个函数清除副作用
返回一个function,当组件卸载的时候,React 会执行清理工作。
effect 在每次 update 都会运行
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);// 只有在 count 发生变化的时候才会执行这个 effect
三、自定义 Hook
有时候我们会想要在组件之间重用一些状态逻辑。目前为止,有两种主流方案来解决这个问题:高阶组件和 render props。自定义 Hook 可以让你在不增加组件的情况下达到同样的目的
function useFriendStatus(id) {
const [status, setStatus] = useState(null);
useEffect(() => {
setTimeout(() => {
setStatus(id + "status")
}, 2000)
}, [])
return status;
}
export default function () {
const tlStatus = useFriendStatus("99")
useEffect(() => {
}, [])
return (<>
<div>
{tlStatus}
</div>
</>)
}
四、其他 Hook
*useContext
让你不使用组件嵌套就可以订阅 React 的 Context。
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
*useReducer
tate 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数
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}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
useCallback
类似于shouldComponentUpdate,该回调函数仅在某个依赖项改变时才会更新。
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
useMemo
仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
useRef
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
useImperativeHandle
父组件中拿到子组件中的state和方法
想限制 ref 的操作权限,我们可以使用 useImperativeHandle 来自定义暴露给父组件的实例值
//父组件:
import React, { useEffect, useState, useRef } from 'react';
import Chen from '../../components/chenwei'
function Tian() {
const childRef = useRef();
useEffect(() => {
}, [])
const getData = () => {
console.log(childRef, "inputElinputEl")
}
return (<>
<div>
<p onClick={getData}>拿到ref</p>
<Chen cRef={childRef} />
</div>
</>)
}
export default React.forwardRef(Tian)
//子组件
import React, { useState, useImperativeHandle } from 'react';
function Wei(props) {
const [data, setData] = useState('chenwei')
const { cRef } = props;
useImperativeHandle(cRef, () => ({
say: "aaaaaaaaaa",
}));
return (<>
<div>
<p>{data}</p>
</div>
</>)
}
export default Wei