Почему все мои компоненты перерисовываются, когда я изменяю несвязанное состояние? - PullRequest
1 голос
/ 28 мая 2019

Я пытаюсь изменить состояние без перезагрузки всего приложения.По какой-то причине этого не происходит, и когда я устанавливаю состояние объекта, который даже не передается определенному компоненту, этот компонент обновляется без причины.

Итак, в приведенном ниже коде ям, когда я устанавливаю сообщение, MainContent не должен перезагружаться.

const [message, setMessage] = useState({});
setMessage('my message'); // This causes the entire app, including 'MyComponent' to reload

return (
    <div className='App'>
        <Header user={user} message={message} setMessage={setMessage} />

        <div id='main-site'>
            <Switch>
                // SHOULD NOT RELOAD UNLESS PASSED IN PROP CHANGED
                <Route path='/main' component={MainContent} />

            </Switch>
        </div>
    </div>
);

Header.jsx

return (
    {message && (
        <div>
            <span>{message.text}</span>
            // This on click makes the entire app reload
            <button className='close' onClick={() => setMessage({})}>
                X
            </button>
        </div>
    )}
);

Как я могу убедиться, что только компоненты, которыеобновляется message реквизит, а другие компоненты не обновляются?

Ответы [ 2 ]

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

Есть два способа исправить вашу проблему.

Первый связан с перемещением вашего состояния вниз к дочернему компоненту, т.е. заголовку, поскольку только заголовок использует состояние message. Еще одна вещь, которую нужно иметь в виду, это то, что вы не вызываете средство обновления состояния непосредственно при рендеринге, поскольку оно будет продолжать вызывать средство обновления состояния реакции, хотя это не повлияет на ваше приложение, поскольку внутренняя реакция предотвращает повторный рендеринг, если в него передается то же состояние. состояние обновления снова.

const [message, setMessage] = useState({});
setMessage('my message');

return (
    {message && (
        <div>
            <span>{message.text}</span>
            // This on click makes the entire app reload
            <button className='close' onClick={() => setMessage({})}>
                X
            </button>
        </div>
    )}
);

Второй способ, который является более надежным способом передачи сообщения более чем одному компоненту, - это использование React.memo для компонента

const MyComponent = () => (
   ...
);

export default React.memo(MyComponent)
0 голосов
/ 28 мая 2019

Вы должны определить хук в функции компонента. которая связывает переменную, и она setMessage обновляет функцию только для этого компонента. В React единственный способ обновить dom - это вызвать все Pure Component или функцию render на React.Component и сравнить там возврат к предыдущему.

Таким образом, чтобы обновить представление после того, как вы изменили его на SetMessage, отреагируйте снова вызовом всей функции рендеринга, чтобы обновить представление.

function MyComponet(){
  return (
    <div className='App'>
        <Header user={user} message={'my message'} />

        <div id='main-site'>
            <Switch>
                // SHOULD NOT RELOAD UNLESS PASSED IN PROP CHANGED
                <Route path='/main' component={MainContent} />

            </Switch>
        </div>
    </div>
);
}


//state that updating when props updating too
function usePropsState(initialState) {
  const [state, setState] = useState(initialState);
  useEffect(() => setState(initialState), [initialState]);
  return [state, setState]
}

function Header({user, message:initMessage}){
  // now you can update the state internally or from outside
  const [message, setMessage] = usePropsState(initMessage);
  return (
    {message && (
        <div>
            <span>{message}</span>
            // This on click makes the entire app reload
            <button className='close' onClick={() => setMessage('')}>
                X
            </button>
        </div>
    )}
  );
}

Если вам нравится этот пользовательский большой палец вверх этот выпуск

...