useRef 和 useContext 等其他 Hooks
其他 Hooks
- useRef
- useContext
- useReducer
- useMemo
- useCallback
useRef 使用
例子
js
import React, { useEffect, useRef } from 'react';
function UseRefDemo() {
const btnRef = useRef(null); // 初始值
const numRef = useRef(100);
console.log(numRef.current); // 100
useEffect(() => {
console.log(btnRef.current); // DOM 节点 <button>click</button>
}, []);
return (
<div>
<button ref={btnRef}>click</button>
</div>
);
}
export default UseRefDemo;
useContext 使用
例子
js
import React, { useContext } from 'react';
const themes = {
light: {
foreground: '#000',
background: '#eee',
},
dark: {
foreground: '#fff',
background: '#222',
},
};
// 创建 Context
const ThemeContext = React.createContext(themes.light);
// 孙子组件
function ThemeButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
hello world
</button>
);
}
// 子组件
function Toolbar() {
return (
<div>
<ThemeButton></ThemeButton>
</div>
);
}
// 父组件
function UseContextDemo() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar></Toolbar>
</ThemeContext.Provider>
);
}
export default UseContextDemo;
useReducer 的使用
useReducer 能代替 redux 吗
- useReducer 是 useState 的替代方案,用于 state 复杂变化
- useReducer 是单个组件状态管理,组件通讯还需要 props
- redux 是全局的状态管理,多组件共享数据
例子
js
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;
}
};
function UseReducerDemo() {
// 很像 const [count,setCount] = useState(0)
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>decrement</button>
</div>
);
}
export default UseReducerDemo;
useMemo 使用
使用 useMemo 做性能优化
- React 默认会更新所有子组件
- class 组件使用 SCU 和 PureComponect 做优化
- Hooks 中使用 useMemo,但优化的原理是相同的
例子
js
import React, { memo, useMemo, useState } from 'react';
// 子组件
// function Child({userInfo}) {
// console.log('child render ...', userInfo)
//
// return <div>
// <p>this is child {userInfo.name} {userInfo.age}</p>
// </div>
// }
// 类似 class PureComponent,对 props 进行浅层比较
const Child = memo(({ userInfo }) => {
console.log('child render ...', userInfo);
return (
<div>
<p>
this is child {userInfo.name} {userInfo.age}
</p>
</div>
);
});
// 父组件
function UseMemoDemo() {
console.log('parent render ...');
const [count, setCount] = useState(0);
const [name, setName] = useState('lzw');
// const userInfo = {name, age: 20}
// 用 useMemo 缓存数据,有依赖
const userInfo = useMemo(() => {
return { name, age: 21 };
}, [name]);
return (
<div>
<p>
count is {count}
<button onClick={() => setCount(count + 1)}>click</button>
</p>
<Child userInfo={userInfo}></Child>
</div>
);
}
export default UseMemoDemo;
useCallback 使用
使用 useCallback 做性能优化
- useMemo 缓存数据
- useCallback 缓存函数
- 两者是 React Hooks 的常见优化策略
例子
js
import React, { memo, useMemo, useState, useCallback } from 'react';
// 子组件, memo 类似 class PureComponent,对 props 进行浅层比较
const Child = memo(({ userInfo, onChange }) => {
console.log('child render ...', userInfo);
return (
<div>
<p>
this is child {userInfo.name} {userInfo.age}
</p>
<input onChange={onChange} />
</div>
);
});
// 父组件
function UseCallbackDemo() {
console.log('parent render ...');
const [count, setCount] = useState(0);
const [name, setName] = useState('lzw');
// 用 useMemo 缓存数据,有依赖
const userInfo = useMemo(() => {
return { name, age: 21 };
}, [name]);
// function onChange(e) {
// console.log(e.target.value)
// }
// 用 useCallback 缓存函数
const onChange = useCallback((e) => {
console.log(e.target.value);
}, []);
return (
<div>
<p>
count is {count}
<button onClick={() => setCount(count + 1)}>click</button>
</p>
<Child userInfo={userInfo} onChange={onChange}></Child>
</div>
);
}
export default UseCallbackDemo;