Open9

Reactのロードマップ

t.kt.k

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で設定するのが望ましい

t.kt.k
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

t.kt.k
function getFakeUsers() {
  return new Promise<fakeUsersProps[]>((resolve) => {
    setTimeout(() => {
      resolve(fakeUsers);
    }, 2000);
  });
}

resolveで返す値に対して、型定義をしている。

t.kt.k

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で逆にこれができなかったのか