Reactのロードマップ
ロードマップを用いてReactを理解していく
promptをsetしても値は引き継がれないのか。
保持する必要のないものの線引が大事かもしれない。
propsでkeyを渡すときは、
const List = ({ users }) => (
<ul>
{users.map(user => <Item key={user.id}>{user.name}</Item>)}
</ul>
);
const Item = ({ key, children }) => (
<p>{key} {children}</p>
);
これだと、keyとしては機能しないので、
const List = ({ users }) => (
<ul>
{users.map(user => (
<Item key={user.id} id={user.id}>
{user.name}
</Item>
))}
</ul>
);
const Item = ({ id, children }) => (
<p>{id} {children}</p>
);
keyとidで設定するのが望ましい
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
hasRadius: boolean;
}
const Input = styled.input<InputProps>`
padding: 0.5em;
margin: 0.5em;
color: palevioletred;
background: papayawhip;
border: none;
border-radius: ${(props) => (props.hasRadius ? "3px" : "0px")};
`;
function App() {
const [value, setValue] = useState("");
return (
<>
<Input
value={value}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setValue(e.target.value)
}
hasRadius={true}
/>
<p>{value}</p>
</>
);
}
disabled等の場合はpropsに直接型定義をすればいいが、オリジナルのプロパティの場合は、extendsを使用する。
参考記事:styled-componentsをTypescriptで使う上でのTips
https://zenn.dev/nekoniki/articles/f8600d1ab7d908
function getFakeUsers() {
return new Promise<fakeUsersProps[]>((resolve) => {
setTimeout(() => {
resolve(fakeUsers);
}, 2000);
});
}
resolveで返す値に対して、型定義をしている。
useRefは値が更新されてもレンダリングされないんだ。
じゃあ何に使えばいいんだ?
useRefはReactのフックの一つで、主に以下の2つの目的で使用されます:
DOM要素にアクセスするため:useRefを使うと、レンダリングを引き起こすことなく直接DOM要素にアクセスできます。これはフォーム要素の値を読み取ったり、フォーカスを設定したりする場合に便利です。
レンダリング間でのデータの保持:useRefはレンダリング間で値を保持することができますが、その値が変更されてもコンポーネントが再レンダリングされることはありません。これはタイマーIDの保持や、以前のprops/stateの値を保持するのに便利です。
DOM要素にアクセスする例
import React, { useRef, useEffect } from 'react';
function TextInputWithFocus() {
const inputEl = useRef(null);
useEffect(() => {
// コンポーネントがマウントされた後にテキスト入力にフォーカスを設定
inputEl.current.focus();
}, []);
return <input ref={inputEl} type="text" />;
}
```jsx
この例では、useRefを使用してinput要素への参照を作成し、コンポーネントがマウントされた後に自動的にフォーカスを設定しています。
レンダリング間でのデータの保持
import React, { useState, useRef, useEffect } from 'react';
function TimerComponent() {
const [timer, setTimer] = useState(0);
const intervalRef = useRef();
useEffect(() => {
intervalRef.current = setInterval(() => {
setTimer((prevTimer) => prevTimer + 1);
}, 1000);
return () => {
clearInterval(intervalRef.current);
};
}, []);
return (
<div>
Timer: {timer}
<button onClick={() => clearInterval(intervalRef.current)}>Stop Timer</button>
</div>
);
}
この例では、useRefを使用してタイマーのインターバルIDを保持しています。コンポーネントがアンマウントされるときに、useEffectのクリーンアップ関数を通じてタイマーをクリアします。また、任意の時点でタイマーを停止するためのボタンも提供しています。ここでuseRefが役立つのは、タイマーIDを保持するためにステートを使ってしまうと、タイマーをクリアするたびにコンポーネントが再レンダリングされてしまう可能性があるからです。
useRefを使用することで、これらの問題を回避しつつ、必要な機能を実装することができます。
なるほど、useStateで逆にこれができなかったのか
routerの勉強開始
こちらの記事を元にReact Routerの理解を深めていく。