React学习系列(三)

react 16中的hooks

function组件中可以使用state和生命周期等class组件的属性

基础HOOKS

useState

function组件中使用state

1
2
const [state, setState] = useState(initialState); // 定义state和更新state的函数,state每次都会返回最新的state值
setState(newState); // 更新state,用法同class组件中的setState

懒初始化state

1
2
3
4
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
}); // 只会在init render中执行一次初始化

useEffect

function组件中使用didMountdidupdatewillUnmout生命周期

1
2
3
4
5
6
7
8
useEffect(() => {
// 在didMount和didupdate生命周期执行
const subscription = props.source.subscribe();
// 返回的方法将会在组件将要卸载时执行
return () => {
subscription.unsubscribe();
};
}, [props.source]); // 第二个参数表示当传入属性变化时才会执行useEffect的回调,避免钩子函数重复执行

useContext

1
const value = useContext(MyContext);

接受一个context对象(数据来自React.createContext),返回当前context对象的最新值。当前context对象指虚拟dom树中最近<MyContext.Provider>的值。当最近的<MyContext.Provider>的上级组件更新时,这个HOOK也会用当前context对象的最新值重绘组件。

附加的HOOKS

useReducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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); // 当initialState为一个函数时只会在第一次初始化时调用,多个组件使用时
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
}

useCallback

只有当依赖[a, b]有更新时才会返回一个新的memoizedCallback,优化子组件的不必要渲染

1
2
3
4
5
6
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b], // 当依赖不提供时每次都会生成一个新的函数
);

useMemo

只有当依赖[a, b]有更新时才会返回一个新的memoizedValue,优化子组件的不必要渲染

1
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); // 当依赖不提供时每次都会生成一个新的值

useRef

获取引用对象

1
2
3
4
5
6
7
8
9
10
11
12
13
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}