🐥
React × TypeScript でのメモアプリ作成 #2(Ref, useRef)
作成日:
2022/01/28
4
学習メモ
フォームに入力した文字を表示するには
- リアルタイムで描写 →
useState
を使う - ボタンを押したときに描写 →
useRef
を使う
参考リンク:
- 【React】input タグの value を取得する方法【useState と useRef の違い】
- useRef は何をやっているのか
- useRef / React Hooks - React入門
useRef の Ref とは
-
要素にRefをアタッチすると、コンポーネント内のどこからでもその要素のDOMにアクセスできるようになる
-
- 例えばinputタグにアタッチした場合は
myRef.current.value
でvalue属性にアクセスできる
- 例えばinputタグにアタッチした場合は
-
便利だけどなにも考えずに使って良いというわけではないらしい
最初はアプリ内で「何かを起こす」ために ref を使いがちかもしれません。そんなときは、少し時間をかけて、コンポーネントの階層のどこで状態を保持すべきかについて、よりしっかりと考えてみてください。多くの場合、その状態を「保持する」ための適切な場所は階層のより上位にあることが明らかになるでしょう。
基本的にはあまりRefに頼らないようにしましょう、ということが随所に書かれています。
コンポーネントに親子関係がある場合、基本的に子コンポーネントの詳細は隠蔽されていますが、Refを利用すると親が子の詳細を知らなくてはならない=依存関係が生まれてしまうためですね。
実際に使ってみる
import classes from "./styles/App.module.scss";
import { useState, useRef } from "react";
export const App = () => {
const inputElement = useRef(null);
const [text, setText] = useState("");
const onClickButton = () => {
setText(inputElement.current.value);
}
return(
<div className={classes.container}>
<h1 className={classes.title}>簡単メモアプリ</h1>
<section className={classes.inputArea}>
<input ref={inputElement} className={classes.inputAreaTextArea} type="text" placeholder="メモを入力" />
<button onClick={onClickButton} className={classes.inputAreaButton}>追加</button>
</section>
<section className={classes.outputArea}>
<h2 className={classes.outputAreaTitle}>メモ一覧</h2>
<p className={classes.outputAreaText}>{text}</p>
</section>
</div>
);
};
上記のコードが実行されると、TypeScriptのエラー。初期値がないとのこと
Object is possibly 'null'.
以下を参考に対処
useRefをTypeScriptで使うと Object is possibly 'null'. と怒られる件の対策
- useRefにDOMの型をつける
const inputElement = useRef<HTMLInputElement>(null);
2. nullの場合の処理をいれる
setText(inputElement.current?.value);
さらにTypeScriptのエラー
Argument of type 'string | undefined' is not assignable to parameter of type 'SetStateAction<string>'.
Type 'undefined' is not assignable to type 'SetStateAction<string>'.
useState
に型を指定していなかったのが原因らしい
以下を参考に対処
ReactのuseStateでTypeScriptの型を複数指定する方法 useState();
const [text, setText] = useState<string | null>();
ボタンを押したらテキストが表示されるところまで完成
所感
TypeScriptのエラーに鍛えられている感じがします…🦍🍌