使用React的useState钩子,防止每次setState时都重新渲染

10

我有一些多状态和使用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返回语句上重新渲染元素。我不想在每个setA,setB,setC等上重新渲染。只要func1或func2完全完成后再重新渲染组件。由于我对hooks很陌生,有人能帮忙吗?

2个回答

4

如果您的状态值深度关联,并且您希望确保一次性更新所有内容:

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: () => false, b: () => {}, }); const updateState = newState => setState(Object.assign({}, state, newState)); 有问题。第一次它可以工作,但后来它没有更新。所以修改了函数如下:let copyState = state; const updateState = newState => { copyState = { ...copyState, ...newState }; setState(copyState); }; 在整个应用程序中,我使用copyState而不是state,因为state的值没有更新。请让我知道是否有遗漏? - Divya
你是否正在使用 updateState 更新状态?这将重新渲染组件。在整个应用程序中使用 copyState 将绕过 React,最终会导致许多难以调试的问题。 - Apolo
当我调用updateState时,组件的重新渲染正在发生,但是state值仍然是旧值。因此,在下一次合并状态时,它只采用初始值,例如{ a: true, b: true, c: data && data.c, d: undefined, e: isChecked ? 'a' : 'b', }。每次都会采用旧值。 - Divya
尝试在组件外声明默认状态,以获得一个恒定的引用。 - Apolo
我修改了代码,像这样:setState(state => ({ ...state, ...{ a: false, b: false }, })),现在它对我有效。 - Divya

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})
}, []);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接