useRef 和 useContext 等其他 Hooks
其他 Hooks
- useRef
- useContext
- useReducer
- useMemo
- useCallback
useRef 使用
例子
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 使用
例子
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 是全局的状态管理,多组件共享数据
例子
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,但优化的原理是相同的
例子
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 的常见优化策略
例子
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