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


133

私は現在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>

また、ソースコードを調べて、useState実装方法を理解することもできます。バージョン16.9の定義は次のとおりです。
chemturion

回答:


148

Reactフックは、stateクラスを使用する必要がないなど、reactのコア機能にアクセスするための新しい方法(まだ開発中)です。たとえば、ハンドラー関数でカウンターを直接インクリメントしたい場合、onClickプロップで直接指定する必要はありません。次のようなことができます:

...
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、カウンターの状態を更新できるようにするメソッドであるタプルを返します。setCounterメソッドを使用してcountどこでも状態を更新できます-この場合、setCount関数内でそれを使用して、さらに多くのことができます。フックのアイデアは、コードをより機能的に保ち、望まない/必要でない場合はクラスベースのコンポーネントを回避できるということです。

私は複数の例でのフックについての完全な記事を書いたような(カウンタを含む)このcodepenを私が利用した、useStateuseEffectuseContext、およびカスタムフック。この回答でフックがどのように機能するかについて詳しく知ることができますが、ドキュメントは状態フックと他のフックを詳細に説明する非常に良い仕事をします、それが役に立てば幸いです。

更新: フックは長くない提案されているバージョン以降、16.8彼らが今使用されるために利用可能です、のサイトを反応させるのではセクションがあり、その答えのいくつかのよくある質問


2
JavaScriptが技術的にタプルデータ型を持たないことを除いて、良いアナロジー
goonerify

まあ、非構造化割り当てはタプルstackoverflow.com/a/4513061/6335029の
NaveenDA

フックは非同期ですか?を使用setSomethingしている場合、somethingその後すぐに使用すると、古い値がまだ残っているようです...
Byron Coetsee

51

useState0.16.7バージョンで利用可能な組み込みの反応フックの1つです。

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

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

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

最初のレンダリング中に返される状態(state)は、最初の引数として渡された値(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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

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

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

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

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


2
例のパラメータとして関数を追加していただきありがとうございます。
ジュニ・ブロサス

15

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

const [value, setValue] = useState(defaultValue)

この構文に慣れていない場合は、ここに移動してください

ドキュメンテーションを読むことをお勧めします。かなりの量の例を含む優れた説明があります。

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>
   );
 }


これは受け入れられる答えになるはずです。簡潔で明快で、外部参照が良好です。
varun

8

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

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

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

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


7

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

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

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

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>

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

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>

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

宜しくお願いします


7

useState()は、機能コンポーネントで状態を使用できるようにする組み込みのReactフックの例です。これは、React 16.7より前は不可能でした。

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


5

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


4

loelsonkさん、ありがとう

const [dataAction, setDataAction] = useState({name: '', description: ''});

    const _handleChangeName = (data) => {
        if(data.name)
            setDataAction( prevState  => ({ ...prevState,   name : data.name }));
        if(data.description)
            setDataAction( prevState  => ({ ...prevState,   description : data.description }));
    };
    
    ....return (
    
          <input onChange={(event) => _handleChangeName({name: event.target.value})}/>
          <input onChange={(event) => _handleChangeName({description: event.target.value})}/>
    )


2

useStateは、機能コンポーネントに状態を追加できるようにするフックです。これは、stateプロパティの初期値である引数を受け入れ、stateプロパティの現在の値と、そのstateプロパティを更新できるメソッドを返します。
以下は簡単な例です:
import React, {useState} from react
function HookCounter {
const [count, stateCount]= useState(0)
return(
<div>
<button onClick{( ) => setCount(count+1)}> count{count} </button>
</div>
)
}

useStateは、この場合はゼロである状態変数の初期値を受け入れ、値のペアを返します。状態の現在の値はcountと呼ばれ、状態変数を更新できるメソッドはsetCountと呼ばれています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.