如何为 React 中构建的用户输入的计算器应用程序重构此代码?

How to refactor this code for a user inputed calculator application built in React?

下面是我到目前为止的代码(这里是沙箱 https://codesandbox.io/s/nice-kirch-i1y58?file=/src/App.js:253-1766).

我的具体重构问题是如何不在 clickHandler 和输出框中复制等式 Math.pow(0.01 * variableTwo * (460 + 26 * variableOne), 1.5。单击处理程序的功能是获取输出字段中的任何值,并将其用作第二个等式的新变量(输出一个变量)。但我不确定该怎么做,所以我只是默认在单击手柄期间再次使用方程式。

export default function App() {


  const [variableOne, setVariableOne] = useState(0);
  const [variableTwo, setVariableTwo] = useState(0);
  const [outputOneVariable, setOutputOneVariable] = useState(0);
  const [link, setLink] = useState(false);

  const clickHandler = () => {
    setOutputOneVariable(
      Math.pow(0.01 * variableTwo * (460 + 26 * variableOne), 1.5)
    );
    setLink(!link);
  };

  return (
    <div className="calculator-page">
      <h1>My Calculator</h1>
      <h3>Calculation One</h3>
      <div className="calculator-one">
        <UserInput
          label="Variable One"
          value={variableOne}
          onChange={(e) => setVariableOne(e.target.value)}
        />
        <UserInput
          label="Variable Two"
          value={variableTwo}
          onChange={(e) => setVariableTwo(e.target.value)}
        />
        <Output
          title="Output One"
          value={Math.pow(0.01 * variableTwo * (460 + 26 * variableOne), 1.5)}
        />
      </div>

      {link ? (
        <LinkOn onClick={clickHandler} />
      ) : (
        <LinkOff onClick={clickHandler} />
      )}

      <h3>Calculation Two</h3>

      <div className="calculator-two">
        <UserInput
          label="Output One Variable"
          value={outputOneVariable}
          onChange={(e) => setOutputOneVariable(e.target.value)}
        />

        <Output
          title="Output Two"
          value={0.0775 * Math.pow(outputOneVariable, 0.46)}
        />
      </div>
    </div>
  );
}

您也可以将数学计算的输出也保存到状态中,然后仅在 variableOne 或 variableTwo 随 useEffect 发生变化时更新它。

  const [outputOneCalc, setOutputOneCalc] = useState(0);

  useEffect(() => {
    setOutputOneCalc(Math.pow(
      0.01 * variableTwo * (460 + 26 * variableOne),
      1.5
    ));
  }, [variableOne, variableTwo]);

然后您可以从点击处理程序和 JSX 中删除计算:

const clickHandler = () => {
    setOutputOneVariable(outputOneCalc);
    setLink(!link);
};

JSX:

<Output
          title="Output One"
          value={outputOneCalc}
        />

https://codesandbox.io/s/pensive-mendeleev-1tbqp?file=/src/App.js

编辑:

迈克的回答是首选和更好的答案。
(你仍然可以阅读我的答案,因为它提供了另一种解决方案+你也可以从中学习)

原答案:

这很容易 (:

您可以将计算逻辑移动到一个单独的函数中, 这将处于组件范围级别。 我们称它为 **calculateOutputOneVariable()**。 (虽然我建议你做一些重命名的工作, 因为 *"Output One"* & *"Output Two"* 至少对我来说没有任何意义)。

在那个单独的函数中,您将像这样实现计算逻辑:

const calculateOutputOneVariable = () => (
    Math.pow(0.01 * variableTwo * (460 + 26 * variableOne), 1.5)
);

然后您可以在 clickHandler() 中使用它并作为输出 value 属性:

const clickHandler = () => {
    setOutputOneVariable(calculateOutputOneVariable());
    setLink(!link);
};

...

return (
    ...
        ...
        <Output
            title="Output One"
            value={calculateOutputOneVariable()}
        />
        ...
    ...
);

*专业提示:*

将第二个内联计算也移动到一个单独的函数(即使它只写了一次)。 如果您命名一些逻辑而不是按原样抛出它,它将更清晰、更易读。

所以,来自:

<Output
  title="Output Two"
  value={0.0775 * Math.pow(outputOneVariable, 0.46)}
/>

它将变成:

<Output
  title="Output Two"
  value={calculateAnotherValue()} // You should ofcourse name it differently
/>