useMemo
1 用作优化当前组件 做数据缓存 防止重绘
function Example() {
const [count, setCount] = useState(1);
const [val, setValue] = useState('');
const getNum = useMemo(() => {
return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
}, [count])
return <div>
<h4>总和:{getNum}</h4>
<div>
<button onClick={() => setCount(count + 1)}>+1</button>
<input value={val} onChange={event => setValue(event.target.value)}/>
</div>
</div>;
}
2 防止子组件重绘
useCallback
function Parent() {
const [count, setCount] = useState(1);
const [val, setValue] = useState('');
const getNum = useCallback(() => {
return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
}, [count])
return <div>
<Child getNum={getNum} />
<div>
<button onClick={() => setCount(count + 1)}>+1</button>
<input value={val} onChange={event => setValue(event.target.value)}/>
</div>
</div>;
}
const Child = React.memo(function ({ getNum }: any) {
return <h4>总和:{getNum()}</h4>
})
useMemo第一个参数是个函数,useMemo返回第一个参数的执行结果,也就是return的值;
useCallback第一个参数也是函数,useCallback返回第一个参数,也就是个函数;
useMemo(() => fn, []) 等同于 useCallback(fn, [])
都需要子组件具备React.memo 才能对比props是否发生改变,如果没变就不重绘子组件
如果子组件没有包React.memo那么就可以这样写
{
useMemo(() => {
return <Child getNum={getNum} />
}, [count])
}
useHistory useLocation
import { useLocation, useHistory } from 'react-router-dom'
const history = useHistory()
const location = useLocation()
// 传参
history.push({
pathname: '/service/contractPreview',
state: { contractViewUrl: 'xxxxx' },
})
// 取值
location.state.contractViewUrl
// 标签传参
<Link
to={{
pathname: `/service/contractPreview`,
state: { contractViewUrl: 'xxxxx' },
}}
>
xxx
</Link>
useReducer
import React, {FC, memo, useCallback, useContext, useMemo, useReducer, useState} from 'react'
interface IGlobalContext {
data: string,
dispatch: Function
}
const GlobalContext = React.createContext<IGlobalContext>({
data: '',
dispatch: () => {}
})
const initialState = {
title: '首页',
color: 'red',
name: 'kong',
data: {
love: 'guanguan'
}
}
const titleReducer = (state: any, action: {type: string, payload: any}) => {
if( action.type === "UPDATE_TITLE_AND_COLOR") {
return action.payload
}else if( action.type === 'UPDATE_NAME_AND_LOVE'){
return {
...state,
name: action.payload.name,
data: action.payload.data
}
}
return state
}
// useMemo优化当前页面 缓存复杂数据 demo
const Happy: FC = () => {
const [data, dispatch] = useReducer(titleReducer, initialState)
return <div>
<GlobalContext.Provider
value={{
data,
dispatch
}}
>
<SubComp />
</GlobalContext.Provider>
</div>
}
const SubComp: FC = () => {
const {data, dispatch} = useContext(GlobalContext)
const changeInfo = () => dispatch({
type: 'UPDATE_TITLE_AND_COLOR',
payload: {
title: '哈哈哈',
color: 'green'
}
})
const changeInfo2 = () => dispatch({
type: 'UPDATE_NAME_AND_LOVE',
payload: {
name: 'guanguan',
data: { love: 'kong' }
}
})
return <div>
{data.title}<br /><br />
<div style={{width: 200, height: 50, backgroundColor: data.color}}></div><br />
<div>{data.name}</div><br />
<div>{data?.data?.love}</div><br />
<button onClick={()=>changeInfo()}>点击更改标题和颜色</button>
<button onClick={()=>changeInfo2()}>点击更改名字和喜欢</button>
</div>
}
export default Happy