【问题标题】:prevent rerender for every setstate using react usestate hook使用 react usestate hook 防止重新渲染每个 setstate
【发布时间】:2020-03-17 10:36:51
【问题描述】:

我有一些多个状态和函数来使用 useState 钩子设置状态。

在每个 setstate 组件上都会重新渲染。我只想重新渲染完全完成的 setstate 功能。

例如:

在 app.js 中

const [a, setA] = useState(() => false);
const [b, setB] = useState(() => {});
const [c, setC] = useState(() => props.c);
const [d, setD] = useState(null);
const [e, setE] = useState(null);
const [f, setF] = useState(null);
const [g, setG] = useState('');

const func1 = useCallback(data => {
  setA(true);
  setB(true);
  setC(data && data.c);
  setD();
  setE(isChecked ? 'a' : 'b');
}, []);

const func2 = useCallback(data => {
  setA(false);
  setB(false);
}, []);

const func3 = useCallback(data => {
  setC(false);
  setD(false);
}, []);

const events = {
  func1,
  func2,
  func3
};

const handleMessage = e => {
  const { eventName, data } = e.data;
  const handleEvents = eventName ? events[toCamel(eventName)] : null;
  if (handleEvents && typeof handleEvents === 'function') {
    handleEvents(data);
  }
};

useLayoutEffect(() => {
  iframe.addEventListener('message', handleMessage, true);
  return () => {
    iframe.removeEventListener('message', handleMessage, true);
  };
}, []);

return (
 <Fragment>
  {a && (
    Component1
  )}
  {b && c && (
    Component2
  )}
</Fragment>

);

在每个 func1 和 func2 的 setA 和 setB 返回语句上重新渲染元素。一旦 func1 或 func2 完全完成,我不想在每个 setA、setB、setC 等上重新渲染,只想重新渲染组件。作为钩子新手,有人可以帮忙吗?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    如果您的状态值关联如此之深,并且您想确保所有内容都立即更新:

    const [state, setState] = useState({
      a: () => false,
      b: () => {},
      c: () => props.c,
      d: null,
      e: null,
      f: null,
      g: ''
    });
    
    const updateState = newState => setState(Object.assign({}, state, newState));
    

    现在当你想更新你的状态时,只需像这样使用updateState

    const func1 = useCallback(
      (data) =>
        updateState({
          a: true,
          b: true,
          c: data && data.c,
          d: undefined,
          e: isChecked ? 'a' : 'b',
        }),
      [],
    );
    

    【讨论】:

    • const [state, setState] = useState({ a: () =&gt; false, b: () =&gt; {}, }); const updateState = newState =&gt; setState(Object.assign({}, state, newState)); 这里有问题。第一次工作,但后来它没有更新。所以修改后的函数如下:let copyState = state; const updateState = newState =&gt; { copyState = { ...copyState, ...newState }; setState(copyState); }; across app 正在使用 copyState 而不是 state。因为状态值没有更新。如果我错过了什么,请告诉我?
    • 您是否正在使用 updateState 更新状态?这应该重新渲染组件。在你的应用程序中使用 copyState 会绕过 React,你最终会遇到很多很难调试的问题
    • 当我调用updateState 时正在重新渲染组件。但state 值仍然是旧值。所以在下一个合并状态下,它只需要像{ a: true, b: true, c: data &amp;&amp; data.c, d: undefined, e: isChecked ? 'a' : 'b', }这样的初始值。每次都取旧值
    • 尝试在组件外部声明默认状态,以获得常量引用
    • 在我这样更改后它对我有用 - setState(state =&gt; ({ ...state, ...{ a: false, b: false }, }))
    【解决方案2】:

    您可以像这样将所有变量存储在一个状态中:

    const [state,setState] = useState({ a:false, b:{}, c:props.c,d:null})
    
    const func1 = useCallback(data => {
    setstate({a:true,b:true,c:data && data.c,d:null})
    }, []);
    

    【讨论】:

      猜你喜欢
      • 2021-02-14
      • 1970-01-01
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多