如何使用 useReducer([state,dispatch]) 和 useContext 避免无用的重新渲染?

Ver*_*std 7 reactjs react-hooks

当使用多个 useReducers 时,使用状态的一部分的每个组件都会重新渲染。

import React, { useContext } from 'react'
import Store from '../store'
import { setName } from "../actions/nameActions"

const Name = () => {
    const { state: { nameReducer: { name } }, dispatch } = useContext(Store)
    const handleInput = ({ target: { value } }) => { dispatch(setName(value)) }
    console.log('useless rerender if other part (not name) of state is changed'); 
    return <div>
        <p>{name}</p>
        <input value={name} onChange={handleInput} />
    </div>
}

export default Name;
Run Code Online (Sandbox Code Playgroud)

如何避免这种无用的重新渲染?

Est*_*ask 10

如果useStateuseReducer状态发生变化,则组件会更新,组件本身无法阻止这种情况。

在依赖于部分状态的子组件中应该防止重新渲染,例如通过使其纯:

const NameContainer = () => {
    const { state: { nameReducer: { name } }, dispatch } = useContext(Store)
    return <Name name={name} dispatch={dispatch}/>;
}

const Name = React.memo(({ name, dispatch }) => {
    const handleInput = ({ target: { value } }) => { dispatch(setName(value)) }
    return <div>
        <p>{name}</p>
        <input value={name} onChange={handleInput} />
    </div>
});
Run Code Online (Sandbox Code Playgroud)

NameContainer可以重写为 HOC 并用于与 Redux 相同的目的connect,从存储中提取所需的属性并将它们映射到连接的组件 props。

  • 这实际上不是一个答案,但是是的,问题是“dispatch”每次都会改变,https://github.com/nickcoleman/hook-use-combined-reducers/blob/master/src/index.js#L9。原始 useReducer 的“dispatch”永远不会改变,因为它应该作为回调传递。这是您使用的第三方库中的错误,请在其存储库中打开一个问题。您可以使用 const dispatchThatNeverChanges = useCallback(dispatch, []) 在 NameContainer 中修复它。 (2认同)