0
2

More than 1 year has passed since last update.

【React】【Hooks】useStateでトグル(toggle)やカウンター(Counter)を実装する際の注意点について

Last updated at Posted at 2022-06-03

はじめに

useStateを使い、前の状態を元に状態を設定する必要がある場合に、通常時のsetItem(〇〇)とは少し違った書き方にすべきことを知ったのでまとめておく。

結論

前の状態を元に状態を設定する必要がある場合には、setCheck(prevIsOpen => !prevIsOpen); という書き方を使う必要がある。

詳細

状態の更新は非同期で行われる可能性があります。

Reactは、パフォーマンスのために、複数のsetState()コールを1回の更新にまとめることがあります。

よって、this.propsthis.stateは非同期に更新される可能性があるので、次の状態に更新するために元々の値をコードに含めてはいけません。

例えば、以下のコードではカウンターの更新に失敗する可能性があります。

this.setState({
  // 新しくsetStateするcounterを計算する際に元々のstateとpropsの値を参照している
  counter: this.state.counter + this.props.increment,
});

この問題を解決するには、オブジェクトではなく以下のような関数を受け取る形式のsetState()を使用します。

// 明示的に、更新前の(state, props)を受け取り、setStateによる更新を行う。
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

HooksのuseStateを用いる場合も同じ用に、書くことができます。

// 何かしらの開閉をisOpenというstateで管理する場合を例にします。
const [isOpen, setIsOpen] = useState(false);

// 更新前のisOpenを受け取り、"!"で反転させる
// 更新前の値であることがわかるように、prev~~とつけても良い
setCheck(prevIsOpen => !prevIsOpen);

おわりに

Hooksの細かい部分ではあるが、setStateが非同期に行われる可能性があることなど、新しい領域のことを学べている実感があった。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2