はじめに
React の学習を始めました。
useState
を学んだタイミングで、復習も兼ねてシンプルな単語管理アプリを作ってみました。
この記事では、その作成を通して得られた学びや気づきを、備忘録としてまとめています。
概要
Reactを用いて作成したシンプルな単語管理アプリです。
- 単語の追加・削除
- 単語の一覧表示
- 習得状態の切り替え
- 習得率の表示
状態管理
今回は、Body
コンポーネントの中に、WordForm
と WordList
の2つの子コンポーネントを作成しました。
最初に悩んだのが、単語をどのように管理をするのか、という点です。
はじめは、表示を担当する WordList
に単語リストを持たせていましたが、
WordForm
から新しい単語を追加しようとしたときに、状態が共有されていないことに気づきました。
最終的には、Body
で単語リストの状態を管理することにしました。
そうすることで、WordForm
と WordList
の両方に props
経由で状態や関数を渡せるようになり、コンポーネント間で状態を共有できました。
スプレッド演算子(...)・map
・filter
これまでの学習ではあまり使う機会がなかった スプレッド演算子(...)・map・filterですが、React のコードを書いていると頻繁に登場し、最初はなかなかうまく使いこなせず苦戦しました。
なぜこれらがよく使われるのかを考えてみると、React では状態を直接変更せず、新しい状態を作ってそれで更新するスタイルが推奨されているからだと気づきました。
そのため、元の状態を壊さずにコピーするために スプレッド演算子 を使います。
const [words, setWords] = useState(wordList);
const createWord = (word) => {
setWords([...words, word]);
};
これは words
配列の内容を展開して、新しい word
を末尾に追加した新しい配列を作成し、それを状態としてセットしています。
既存の状態を変更せず、新しい配列を作成していることになります。
また、配列の特定要素を更新したいときには map
を使います。
const updateWord = (targetWord, updatedWord) => {
setWords(words.map((word) => (word === targetWord ? updatedWord : word)));
};
これは、すべての単語に対して targetWord
と一致するかを確認し、
一致した要素だけを updatedWord
に置き換え、それ以外はそのまま返すという処理です。
結果として、新しい配列が返り、それを状態として更新しています。
逆に、特定の要素を削除したい場合は filter
を使います。
const deleteWord = (targetWord) => {
setWords(words.filter((word) => word != targetWord));
};
これは、targetWord
に一致しない単語だけを残した配列を新しく作成し、状態として反映させています。
また、配列 → JSX 要素の変換に map
が活躍します。
<ul>
{words.map((word) => (
<li key={`${word.english}: ${word.japanese}`}>
{word.english}: {word.japanese}
</li>
))}
</ul>
感想
- JavaScriptで DOM を直接操作しなくて済むのは、とても快適に感じました
- 状態管理の考え方や、状態を親から子に渡す仕組みについて最初は戸惑いましたが、使っていくうちに少しずつ理解できてきた気がします