質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

134閲覧

React/Next でマウント時にatomWithStorageの値を読み込みたいのですができません。。。

Hayato1201

総合スコア228

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2024/05/10 02:58

編集2024/05/10 02:58

実現したいこと

jotai の atomWithStorage を使用しています。
以下のように useEffect の第二引数に[]を指定することでマウント時に一度だけ atomWithStorage の値を読み込んで処理を行いたいです。
しかしこれだと storedValue に値があっても undefined となってしまう様です。第二引数に storedValue を追加すれば実行されるため、タイミング的な問題でしょうか? jotai の atom に限らず useRouter の route だったりもそのような現象があったと思います。
ただ第二引数に追加する、だと他のタイミンングで storedValue が更新された場合にも実行されてしまいます。

ts

1const [storedValue, setStoredValue] = useAtom(atom); 2 3 useEffect(() => { 4 if (storedValue) { 5 //do something 6 } 7 }, []);

ts

1export const atom = atomWithStorage<StoredValue>("storedValue", initialState);

そもそも上記のような使い方をすると以下の様な warn が出てきますが、このような使い方は推奨されていないのでしょうか?
React Hook useEffect has a missing dependency: 'storedValue'. Either include it or remove the dependency array.
だとしたらマウント時にのみ storedValue を確認して処理を実行したい時、どのようにすれば良いのでしょか?ご教示いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

「マウント時に読み込むだけ」であれば、むしろステート→useEffectと連鎖させることで遠回りになってしまっている気がします。普通に useEffect の中に読み込み処理を直に書いたほうが良いと思います。

atomWithStorage は、結局中で JSON への変換と as 型 での型チェック回避を行っているだけなので、それを自分で書くだけで OK なはずです。

(ちゃんとチェックしたいなら、Zod とか Valibot みたいなスキーマライブラリを使うと良いかもしれません!)

tsx

1const [value, setValue] = useState<StoredValue | undefined>(undefined); 2useEffect(() => { 3 const raw = localStorage.getItem("storedValue"); 4 if(raw == null) return; 5 6 const jsonData = JSON.parse(raw) as StoredValue; 7 setValue(jsonData) 8], []);

そもそも上記のような使い方をすると以下の様な warn が出てきますが、このような使い方は推奨されていないのでしょうか?
React Hook useEffect has a missing dependency: 'storedValue'. Either include it or remove the dependency array.

余談ですが、「推奨されてない」と考えてよいと思います。

依存配列がコードと一致しない場合、バグが発生するリスクが非常に高くなります。リンタを止めることで、エフェクトが依存する値について React に「嘘」をついていることになります。

代わりに、以下にある手法を使用してください。

https://ja.react.dev/learn/removing-effect-dependencies#to-change-the-dependencies-change-the-code

投稿2024/05/15 13:03

honey32

総合スコア199

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問