reactjs - React hooks 如何更好地根据 props 变化更新多个状态

标签 reactjs react-hooks

假设我有一个包含排序数据的表,我想将其存储在 state 上(甚至 3 个独立的状态)。假设这个状态可以被 child 改变。 无论如何,有没有办法在没有 3 个不同的 useEffects 的情况下做到这一点? ,我想看看能否仅使用1次使用效果达到如下效果?

import React, { useState, useEffect } from "react";

function Table({ initialSortDirection, initialSortParam, initialSortEnabled }) {
    const [currentSortData, setSortData] = useState({
        sortDirection: initialSortDirection,
        sortParam: initialSortParam,
        hasSort: initialSortEnabled
    });
    useEffect(() => {
        setSortData({ ...currentSortData, sortDirection: initialSortDirection });
    }, [initialSortDirection]);
    useEffect(() => {
        setSortData({ ...currentSortData, sortParam: initialSortParam });
    }, [initialSortParam]);
    useEffect(() => {
        setSortData({ ...currentSortData, hasSort: initialSortEnabled });
    }, [initialSortEnabled]);
   return (<SomeComponent onChangeSort={setSortData} />)
}

按照传统的方式,我可能会使用 componentWillReceiveProps并比较 nextProps 看看它们是否发生了变化,但现在我很难找到一种简洁的方法来“立即”并且仅在发生变化时执行此操作。

作为一个可视化示例,请考虑下图,您可以通过单击单元格或更改“旋钮”来更改排序。 enter image description here 编辑1

假设其他事情可能会影响状态,并且我不想用未更改的初始 prop 覆盖更新后的状态。我相应地更新了代码

编辑2 添加了故事书图片

最佳答案

这是您正在寻找的行为吗?

以下是我仅使用一个 useEffect() 即可实现的方法。

我会将 props 最后的值(来自之前的渲染)保留在 useRef 中,并检查每个属性的差异,并决定是否应该更新状态。之后,我将 ref 值更新为当前 props,以便在下一次渲染等过程中对照 future 的 props 进行检查。

function App() {

const [initialState, setInitialState] = React.useState({
  initialProp1: 'A',
  initialProp2: 'A'
});

return(
    <Table
      {...initialState}
      setInitialState={setInitialState}
    />
  );
}

function Table({initialProp1, initialProp2, setInitialState}) {
  const [myState, setMyState] = React.useState({
    prop1: initialProp1,
    prop2: initialProp2
  });
  
  const lastProps = React.useRef({
    initialProp1, 
    initialProp2
  });
  
  React.useEffect(()=>{
    if (lastProps.current.initialProp1 !== initialProp1) {
      console.log('1 changed');
      setMyState((prevState)=>{
        return({
          ...prevState,
          prop1: initialProp1
        });
      });
    }
    if (lastProps.current.initialProp2 !== initialProp2) {
      console.log('2 changed');
      setMyState((prevState)=>{
        return({
          ...prevState,
          prop2: initialProp2
        });
      });
    }
    lastProps.current = {
      initialProp1,
      initialProp2
    }
  });
  
  function changeState() {
    setMyState((prevState) => {
      return({
        ...prevState,
        prop2: 'B'
      });
    });
  }
  
  function changeProps() {
    setInitialState({
      initialProp1: 'A',
      initialProp2: 'C'
    });
  }
  
  return(
  <React.Fragment>
    <div>This is Table <b>props</b> initialProp1: {initialProp1}</div>
    <div>This is Table <b>props</b> initialProp2: {initialProp2}</div>
    <div>This is Table <b>state</b> prop1: {myState.prop1}</div>
    <div>This is Table <b>state</b> prop2: {myState.prop2}</div>
    <button onClick={changeState}>Change Table state</button>
    <button onClick={changeProps}>Change props that comes from parent</button>
  </React.Fragment>
  );
  
}


ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关于reactjs - React hooks 如何更好地根据 props 变化更新多个状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56473210/

相关文章:

reactjs - React-tabs 的自定义样式

javascript - 如何使用 React Native 集成 Stripe 并符合 PCI 标准?

reactjs - React SSR,处理页面滚动位置的正确方法

reactjs - 如何在某些情况下删除 React hook?

javascript - 动态获取功能组件的 ref - ReactJS

javascript - 在 React 无状态组件中存储不可观察数据的最佳方法(使用 Hooks)

reactjs - 第 0 行 : Parsing error: Cannot read property 'map' of undefined

javascript - 使用 useState 时,React 不会在状态更改时重新渲染

javascript - 如何在 react 中验证多步表单

html - 在React中使用callback ref修改scrollLeft属性