Как избежать бесполезного повторного рендеринга с использованием useReducer ([state, dispatch]) и useContext? - PullRequest
0 голосов
/ 29 мая 2019

При использовании нескольких 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;

Как избежать этой бесполезной перерисовки?

Ответы [ 2 ]

2 голосов
/ 29 мая 2019

Если состояние useState или useReducer изменяется, компонент обновляется, и в самом компоненте предотвратить это невозможно.

Повторная визуализация должна быть предотвращена в дочернем компоненте, который зависит от частичного состояния, например, сделав его чистым:

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>
});

NameContainer можно переписать в HOC и использовать для тех же целей, что и Redux connect, для извлечения необходимых свойств из хранилища и сопоставления их с реквизитами подключенных компонентов.

0 голосов
/ 30 мая 2019

Я попробовал ваше решение без удачи ...

Я использую-комбинированные-редукторы использования от https://www.npmjs.com/package/@nickcoleman/use-combined-reducers. Возможно ли, что диспетчер обновляется каждый раз, поэтому каждый раз создается новая функция ... Даже если другая часть состояния изменяется, он воссоздает диспетчеризация, так что это вызывает повторное рендеринг, потому что диспетчеризация всегда отличается?

Как мне это решить?

...