web-dev-qa-db-ja.com

ReactのuseState()とは何ですか?

現在、Reactでフックの概念を学習しており、以下の例を理解しようとしています。

    import { useState } from 'react';

    function Example() {
        // Declare a new state variable, which we'll call "count"
        const [count, setCount] = useState(0);

      return (
         <div>
            <p>You clicked {count} times</p>
           <button onClick={() => setCount(count + 1)}>
               Click me
           </button>
        </div>
     );
 }

上記の例は、ハンドラー関数パラメーター自体のカウンターを増分します。イベントハンドラー関数内のカウント値を変更する場合

以下の例を検討してください

    setCount = () => {
        //how can I modify count value here. Not sure if I can use setState to modify its value
        //also I want to modify other state values as well here. How can I do that
    }

    <button onClick={() => setCount()}>
               Click me
     </button>
34
Hemadri Dasari

React hooks は、クラスを使用せずにstateなどのreactのコア機能にアクセスするための新しい方法です(開発中)。例では、ハンドラー関数で直接カウンターをインクリメントしたくない場合onClick propで直接指定すると、次のようなことができます。

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};

およびonClick:

<button onClick={setCount}>
    Click me
</button>

この行で何が起こっているかを簡単に説明しましょう:

const [count, setCounter] = useState(0);

useState(0)は、最初のパラメーターcountがカウンターの現在の状態で、setCounterがカウンターの状態を更新できるメソッドであるTupleを返します。 setCounterメソッドを使用して、countの状態をどこでも更新できます。この場合、setCount関数内で使用して、より多くのことを実行できます。フックのアイデアは、コードをより機能的に保ち、必要とされない場合はクラスベースのコンポーネントを回避できるということです。

複数の例があるフックについての完全な記事を書きました (カウンターを含む) this codepen など、useStateuseEffectuseContext、およびcustom hooks。この回答でフックがどのように機能するかについてさらに詳しく知ることができましたが、ドキュメントは state hook およびその他のフックを詳細に説明し、それが役立つことを願っています。

update:フックはもはや提案ではありません 、バージョン16.8使用できるようになりました。Reactのサイトには FAQ のいくつかに答えるセクションがあります。

32
Enmanuel Duran

useStateは、0.16.7バージョンで使用可能な組み込みのリアクションフックの1つです。

useStateは、機能コンポーネント内でのみ使用する必要があります。 useStateは、内部状態が必要であり、ライフサイクルメソッドなどのより複雑なロジックを実装する必要がない場合の方法です。

const [state, setState] = useState(initialState);

ステートフル値と、それを更新する関数を返します。

最初のレンダリング中、返される状態(状態)は、最初の引数(initialState)として渡された値と同じです。

SetState関数は、状態を更新するために使用されます。新しい状態値を受け入れ、コンポーネントの再レンダリングをキューに入れます。

注意useStateは状態を更新するためのコールバックをフックします異なる動作コンポーネントthis.setStateより。違いを示すために、2つの例を用意しました。

class UserInfoClass extends React.Component {
  state = { firstName: 'John', lastName: 'Doe' };
  
  render() {
    return <div>
      <p>userInfo: {JSON.stringify(this.state)}</p>
      <button onClick={() => this.setState({ 
        firstName: 'Jason'
      })}>Update name to Jason</button>
    </div>;
  }
}

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <UserInfoClass />
    <UserInfoFunction />
  </div>
, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

setUserInfoコールバックが使用されると、新しいオブジェクトが作成されます。 lastNameキー値を失ったことに注意してください。 useState内で関数を渡すことができることを修正しました。

setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })

例を参照:

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo(prevState => ({
        ...prevState, firstName: 'Jason' }))}>
        Update name to Jason
      </button>
    </div>
  );
}

ReactDOM.render(
    <UserInfoFunction />
, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

クラスコンポーネントにあるsetStateメソッドとは異なり、useStateは更新オブジェクトを自動的にマージしません。関数アップデータフォームとオブジェクトスプレッド構文を組み合わせることで、この動作を再現できます。

setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

useStateの詳細については、 公式ドキュメント を参照してください。

16
loelsonk

useStateは、React v16.8.0で使用可能なフックの1つです。基本的に、それ以外の場合は非ステートフル/機能コンポーネントを、独自の状態を持つことができるコンポーネントに変えることができます。

非常に基本的なレベルでは、次のように使用されます。

const [isLoading, setLoading] = useState(true);

これにより、setLoadingを呼び出してブール値を渡すことができます。これは、「ステートフル」な機能コンポーネントを持つクールな方法です。

5
John Kennedy

useStateフックの構文は簡単です。

const [value, setValue] = useState(defaultValue)

この構文に慣れていない場合は、 here に進みます。

ドキュメント を読むことをお勧めします。まともな量の例とともに優れた説明があります。

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);
  
  // its up to you how you do it
  const buttonClickHandler = e => {
   // increment
   // setCount(count + 1)
   
   // decrement
   // setCount(count -1)
   
   // anything
   // setCount(0)
  }
  

  return (
       <div>
          <p>You clicked {count} times</p>
         <button onClick={buttonClickHandler}>
             Click me
         </button>
      </div>
   );
 }
5
Jan Ciołek

useState()は、機能コンポーネントで状態を使用できるビルトインReactフックの例です。これはReact 16.7以前では不可能でした。

UseState関数は、reactパッケージからインポートできる組み込みフックです。機能コンポーネントに状態を追加できます。関数コンポーネント内でuseStateフックを使用すると、クラスコンポーネントに切り替えることなく状態の一部を作成できます。

注:フックは現在アルファ版であるため、まだ生産の準備ができていないことに注意してください。これは、APIが変更される可能性があることも意味します。

3

フックはReact v16.7.0-alphauseStateの新しい機能であり、「フック」です。 useState() any変数のデフォルト値を設定し、関数コンポーネント(PureComponent関数)で管理します。 ex : const [count, setCount] = useState(0);はカウント0のデフォルト値を設定します。uはsetCountincrimentまたはdecrimentの値に使用できます。 onClick={() => setCount(count + 1)}カウント値をインクリメントします。 DOC

3
Asif vora

useState()はReactフックです。フックを使用すると、関数コンポーネント内で状態と可変性を使用できます。

クラス内でフックを使用することはできませんが、クラスコンポーネントを関数1でラップし、そこからフックを使用することができます。これは、コンポーネントをクラスから関数形式に移行するための優れたツールです。完全な例を次に示します。

この例では、カウンターコンポーネントを使用します。これです:

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: props.count };
  }
  
  inc() {
    this.setState(prev => ({count: prev.count+1}));
  }
  
  render() {
    return <button onClick={() => this.inc()}>{this.state.count}</button>
  }
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

これは、カウント状態を持つ単純なクラスコンポーネントであり、状態の更新はメソッドによって行われます。これは、クラスコンポーネントの非常に一般的なパターンです。最初のことは、すべてのプロパティをラップされたコンポーネントに委任する、同じ名前の関数コンポーネントでラップすることです。また、関数戻りでラップされたコンポーネントをレンダリングする必要があります。ここにあります:

function Hello(props) {
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => this.inc()}>{this.state.count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

これはまったく同じコンポーネントで、同じ動作、同じ名前、同じプロパティです。次に、カウント状態を関数コンポーネントに持ち上げましょう。これは、次のとおりです。

function Hello(props) {
  const [count, setCount] = React.useState(0);
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => setCount(count+1)}>{count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>

メソッドincはまだ存在し、誰も傷つけないことに注意してください。実際にはデッドコードです。これがアイデアであり、状態を上げ続けるだけです。終了したら、クラスコンポーネントを削除できます。

function Hello(props) {
  const [count, setCount] = React.useState(0);

  return <button onClick={() => setCount(count+1)}>{count}</button>;
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>

<div id='root'></div>

これにより、クラスコンポーネント内でフックを使用できるようになりますが、この例のように移行する場合を除き、フックを使用することはお勧めしません。関数とクラスのコンポーネントを混在させると、状態管理が混乱します。これが役立つことを願っています

宜しくお願いします

1
geckos