Home > Blockchain >  React Usestate syntax mentions name twice
React Usestate syntax mentions name twice

Time:10-08

Learning react for the very first time.

I am looking at the useState hook pattern which looks something like this:

    const [count, setCount] = useState(0);
 
    const increase = () => {
        setCount(count 1);
    }

I am bothered by the fact that I need to mention the literal count twice. Not to mention that the order of the returned values is implicit: There is nothing preventing you from making the 2 A.M. error of getting your array in false order such as [count,typo,setCount]=... .

Javascript being an Object Oriented language, I would expect something more resilient like:

    const count = useState(0);
 
    const increase = () => {
        count.set( count.value   1 ); // I would argue that maybe even count.value()
    }

Why does the default react hook pattern declare two literals (count & setCount)?

  1. Is there some advantage to this syntax?
  2. Is there a common pattern/lib which I can use to write code in the second (one literal) style?
    • If there is no such established pattern, is there any reason I should not create one?
      • I am a react novice, trying to understand the design of the framework. Is there some design principle I am missing which prefers the current 2 declaration syntax?

CodePudding user response:

While such an object-oriented approach could have been designed, React functional components have chosen to take a more functional approach instead - where, rather than having (possibly mutable) objects be passed around with methods, there's more of a focus on individual identifiers and (if desired) primitive state values in plain variables.

If you prefer an object approach, it's easy enough to create a custom hook for that.

const useObjectState = (initialValue) => {
  const [state, setState] = React.useState(initialValue);
  return {
    value: state,
    set: setState,
  };
};
const App = () => {
    const count = useObjectState(0);
    const increase = () => {
        count.set( count.value   1 );
    };
    return (
      <div>
        <button onClick={increase}>click</button>
        <div>{count.value}</div>
      </div>
    );
};

ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

That said, a more maintainable codebase (for other developers) would likely follow the existing React patterns, rather than creating your own slightly different ones.

Is there a common pattern/lib which I can use to write code in the second (one literal) style?

One option is to use class-based components instead of functional components, which use this.state and this.setState.

class App extends React.Component {
  state = { count: 0 }
  increase = () => {
    this.setState({ count: this.state.count   1 });
  }
  render() {
    return (
      <div>
        <button onClick={this.increase}>click</button>
        <div>{this.state.count}</div>
      </div>
    );
  }
};

ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

  • Related