【问题标题】:Delay update of calculated value until some required state has been set延迟更新计算值,直到设置了一些所需的状态
【发布时间】:2020-11-04 14:45:36
【问题描述】:

我正在寻求一些帮助,以延迟某些计算数据的显示,直到它所依赖的状态在父组件中设置。在下面的简化示例中,App 的值设置为 0,然后运行一些计算并更新状态。

问题是当Calculate被点击时,更新初始val状态的计算还没有发生,因此从calcOverUnderPayment推导出的最终值是不正确的。

它只会在所有后续点击中显示正确的值。

我能做些什么来解决这个问题?

非常感谢。

function App() {
  const [val, setVal] = useState(0)

  const calculate = () => {
    // code to run some calculations which I then set as state
    setVal(100)
  }

  return (
    <>
      <button onClick={() => calculate()}>Calculate</button>
      <Outcome
        val={val}
      />
    </>
  )
}

function Outcome(val) {
  const calcOverUnderPayment = (value: number, type: string) => {
    if (type === 'under') {
      return (value > 0) ? value : 0
    } else {
      return (value < 0) ? value : 0
    }
  }

  return (
    <>
      Final Val is {calcOverUnderPayment(val)}
    </>
  )
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    我在另一个答案上浏览了你的 cmets。您可以在 Outcome 组件中使用另一个状态变量和 useEffect 挂钩。

    function App() {
      // If it is possible, try to change the initial value to null so that the Outcome component can figure out when did the value change.
      const [val, setVal] = useState(null)
    
      const calculate = () => {
        // code to run some calculations which I then set as state
        setVal(100)
      }
    
      return (
        <>
          <button onClick={() => calculate()}>Calculate</button>
          <Outcome
            val={val}
          />
        </>
      )
    }
    
    function Outcome({ val }) {
      // Use this state to display initial value and update this state instead of calling the function directly in the return
      const [valueToDisplay, setValueToDisplay] = useState('YOUR_INITIAL_VALUE_TO_DISPLAY');
    
      const calcOverUnderPayment = (value: number, type: string) => {
        if (type === 'under') {
          return (value > 0) ? value : 0
        } else {
          return (value < 0) ? value : 0
        }
      }
    
     // use useEffect hook to run your function whenever val prop is changed 
      useEffect(() => {
        // If the val prop is null, then it is evident that it is rendering for the first time. 
        // So, don't run the calcOverUnderPayment() method. This is why "null" is important to provide as your initial state for "val" in App component
        if(val !== null) {
          const value = calcOverUnderPayment();
          // set the state variable here to display
          setValueToDisplay(value);
        }
      },[val]) // Give the val prop as the dependency. This tells useEffect to run whenever val prop is changed.
    
      return (
        <>
          {/* Instead of calling your function here, use the state variable*/}
          Final Val is {valueToDisplay}
        </>
      )
    }
    

    这应该可以按您的预期工作。如果您遇到任何问题或不明白,请告诉我。

    【讨论】:

    • 道歉,我以为我已经道歉了,现在可以了。再次感谢您的帮助。
    【解决方案2】:

    作为选项之一,您可以只使用条件渲染并渲染您的子组件,仅当状态不是默认值时,在您的情况下,这样的事情会做:

      return( //your components here 
            {val != 0 && <Outcome val={val} />}
           //rest of your component
      )
    

    【讨论】:

    • 这是一个不错的选择,但在这种情况下不起作用,因为我需要已经显示组件,此外,特定的 val 可能为零,并且仍然需要在其他部分上运行一些计算来生成需要显示的结果。
    • 好吧,我不清楚您到底需要什么,那是什么计算?也许你只是做另一个 useState(false) -> 如果你的计算正在进行中,它会标记你,并且基于此你可以做任何你需要做的事情(此时我还不清楚)
    • useState(false) 是一个选项,但我使用 setState 设置了三个不同的值。如何确定所有这三个值的状态何时更新以更改 false 标志的布尔值?我将更新我的问题以更清楚我的要求
    • 这很有趣,是的,需要准确地看到你的问题,但你可以将你的 3 个值放入一个状态对象,然后使用类似这样的东西 - stackoverflow.com/questions/53446020/…
    猜你喜欢
    • 2016-02-24
    • 2017-10-09
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多