简化 React 状态更新?

huangapple go评论102阅读模式
英文:

Simplify react state update?

问题

我正在构建一个简单的React应用程序,我想根据特定条件更新组件的状态。目前,我正在使用一个硬编码的解决方案,它可以工作,但似乎过于复杂,我想知道是否有一种更简单的方法来实现相同的结果。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      value: 'initial'
    };
  }

  handleClick() {
    this.setState((prevState) => {
      if (prevState.count === 0) {
        return { count: prevState.count + 1, value: 'clicked once' };
      } else if (prevState.count === 1) {
        return { count: prevState.count + 1, value: 'clicked twice' };
      } else {
        return { count: prevState.count + 1, value: 'clicked many times' };
      }
    });
  }

  render() {
    return (
      <div>
        <p>{this.state.value}</p>
        <button onClick={() => this.handleClick()}>Click me</button>
      </div>
    );
  }
}

这个方法可以工作,但随着条件数量的增加,变得不够可扩展并且难以管理。

英文:

I'm building a simple react application and I want to update the state of a component based on certain conditions. Currently, I'm using a hardcoded solution that works, but it seems too complicated and I want to know if there is a simpler way to achieve the same result.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      value: &#39;initial&#39;
    };
  }

  handleClick() {
    this.setState((prevState) =&gt; {
      if (prevState.count === 0) {
        return { count: prevState.count + 1, value: &#39;clicked once&#39; };
      } else if (prevState.count === 1) {
        return { count: prevState.count + 1, value: &#39;clicked twice&#39; };
      } else {
        return { count: prevState.count + 1, value: &#39;clicked many times&#39; };
      }
    });
  }

  render() {
    return (
      &lt;div&gt;
        &lt;p&gt;{this.state.value}&lt;/p&gt;
        &lt;button onClick={() =&gt; this.handleClick()}&gt;Click me&lt;/button&gt;
      &lt;/div&gt;
    );
  }
}

This works, but it's not scalable and becomes hard to manage as the number of conditions increases.

答案1

得分: 0

你可以使用条件运算符。

this.setState(prevState => ({count: prevState.count + 1, value: 
'clicked ' + (prevState.count === 0 ? 'once' : prevState.count === 1 ? 'twice' : 'many times')}));
英文:

You can use the conditional operator.

this.setState(prevState =&gt; ({count: prevState.count + 1, value: 
&#39;clicked &#39; + (prevState.count === 0 ? &#39;once&#39; : prevState.count === 1 ? &#39;twice&#39; : &#39;many times&#39;)}));

答案2

得分: 0

您正因value状态是一种反模式而感到压力。它是count的派生值,不应该有自己的状态。也就是说,count是您的唯一真相源 -

function App() {
  const [count, setCount] = React.useState(0)
  const onClick = event => setCount(c => c + 1)
  return (
    <div>
      <button onClick={onClick} children="click" />
      <p>
        {count == 0 
          ? "initial" // derived from count
          : count == 1
          ? "clicked once"
          : count == 2
          ? "clicked twice"
          : "clicked many times"
        }
      </p>
    </div>
  )
}

ReactDOM.createRoot(document.querySelector("#app")).render(<App />)

作为一个基于类的组件,可能会像这样 -

class App extends React.Component {
  state = { count: 0 }
  onClick = e =>  this.setState(s => ({ count: s.count + 1 }))
  render() {
    return (
      <div>
        <button onClick={this.onClick} children="click" />
        <p>
          {this.state.count == 0 // derived from count
            ? "initial"
            : this.state.count == 1
            ? "clicked once"
            : this.state.count == 2
            ? "clicked twice"
            : "clicked many times"
          }
        </p>
      </div>
    )
  }
}

ReactDOM.createRoot(document.querySelector("#app")).render(<App />)

(请注意,这是代码的翻译,不包括代码部分)。

英文:

You are experiencing stress because your value state is an anti-pattern. It is a derivative of count and should not have state of its own. That is to say count is your single source of truth -

<!-- begin snippet: js hide: false console: true babel: true -->

<!-- language: lang-js -->

function App() {
  const [count, setCount] = React.useState(0)
  const onClick = event =&gt; setCount(c =&gt; c + 1)
  return &lt;div&gt;
    &lt;button onClick={onClick} children=&quot;click&quot; /&gt;
    &lt;p&gt;
      { count == 0 
      ? &quot;initial&quot; // derived from count
      : count == 1
      ? &quot;clicked once&quot;
      : count == 2
      ? &quot;clicked twice&quot;
      : &quot;clicked many times&quot;
      }
    &lt;/p&gt;
  &lt;/div&gt;
}

ReactDOM.createRoot(document.querySelector(&quot;#app&quot;)).render(&lt;App /&gt;)

<!-- language: lang-html -->

&lt;script crossorigin src=&quot;https://unpkg.com/react@18/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script crossorigin src=&quot;https://unpkg.com/react-dom@18/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

As a class-based component, that might look like this -

<!-- begin snippet: js hide: false console: true babel: true -->

<!-- language: lang-js -->

class App extends React.Component {
  state = { count: 0 }
  onClick = e =&gt;  this.setState(s =&gt; ({ count: s.count + 1 }))
  render() {
    return &lt;div&gt;
      &lt;button onClick={this.onClick} children=&quot;click&quot; /&gt;
      &lt;p&gt;
        { this.state.count == 0 // derived from count
        ? &quot;initial&quot;
        : this.state.count == 1
        ? &quot;clicked once&quot;
        : this.state.count == 2
        ? &quot;clicked twice&quot;
        : &quot;clicked many times&quot;
        }
      &lt;/p&gt;
    &lt;/div&gt;
  }
}

ReactDOM.createRoot(document.querySelector(&quot;#app&quot;)).render(&lt;App /&gt;)

<!-- language: lang-html -->

&lt;script crossorigin src=&quot;https://unpkg.com/react@18/umd/react.development.js&quot;&gt;&lt;/script&gt;
&lt;script crossorigin src=&quot;https://unpkg.com/react-dom@18/umd/react-dom.development.js&quot;&gt;&lt;/script&gt;
&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月14日 02:34:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439937.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定