更改不相关状态后,为什么我的所有组件都会重新渲染?

时间:2019-05-28 00:36:17

标签: javascript reactjs render react-hooks

我正在尝试更改状态而不重新加载整个应用程序。出于某种原因,这种情况没有发生,当我设置一个对象的状态甚至没有传递给特定组件时,该组件就会无故更新。

因此在下面的代码中,我是在设置消息时$update_pl['rol_colegio'] = $rol_colegio; //$rol_colegio may be null $usuario->update($update_pl); 不应重新加载。

MainContent

Header.jsx

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

如何确保只有具有return ( {message && ( <div> <span>{message.text}</span> // This on click makes the entire app reload <button className='close' onClick={() => setMessage({})}> X </button> </div> )} ); 道具的组件得到更新,而没有其他组件重新渲染?

2 个答案:

答案 0 :(得分:0)

您应该在组件函数中定义钩子。绑定变量,并且setMessage仅将函数更新到该组件。 在React中,更新dom的唯一方法是通过调用render上的所有Pure Component或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>
    )}
  );
}

如果您喜欢这个自定义的“竖起大拇指” this问题

答案 1 :(得分:0)

有两种方法可以解决您的问题。

第一个涉及将状态下移到子组件,即Header,因为只有Header使用message状态。要记住的另一件事是,您不会直接在render中调用状态更新程序,因为它将继续调用react state updater,尽管它不会影响您的应用程序,因为如果提供相同的状态,则内部会阻止re-render。状态更新器。

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)