Open17

Reactについて調べたこと

mskmsk

Sandbox的にindex.htmlで記述する方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <div id="container"></div>
    <script type="text/babel">
        'use strict';

        {
            const container = document.getElementById('container');
            const root = ReactDOM.createRoot(container);
            root.render(
                <div>
                    <h1>Hello, world!</h1>
                    <h2>It is {new Date().toLocaleTimeString()}.</h2>
                </div>
            );
        }
    </script>
</body>
</html>
mskmsk

JSX記法

  • 単一のルート要素を返す。複数返したい場合は<React.Fragment>もしくは<>で囲む。
<>
</>
  • すべてのタグを閉じる
  • キャメルケースで記述する。
  • babel/standaloneでトランスコンパイルできる。<script type="text/babel">の記述でコンパイルされる。
  • JavaScriptの式は{}で囲んで記述することができる。bool型は何も出力されない。
    式と分の違いは、式は値を返す。文は変数宣言、for・if・swtich文など。
    1は式文。
  • JSX - babel -> JSオブジェクト -> React要素のように変換される。
mskmsk

CSSのclassについて

  • classNameで記述する
<div className="class1">
</div>
mskmsk

コンポーネント

const App = () => {
    return (
        <>
        </>
    );
};
mskmsk

prosで値を受け取る、{}で囲って値を表示する

  • 通常の受け方
<script type="text/babel">
    'use strict';

    {
        const container = document.querySelector('#container');
        const root = ReactDOM.createRoot(container);
        const Item = (props) => {
            return (
                <li>{props.value}</li>
            );
        }
        const App = () => {
            return (
                <>
                    <div>
                        <ul>
                            <Item value="Hello" />
                            <Item value="World" />
                            <Item value="React" />
                        </ul>
                        <h2>It is {new Date().toLocaleTimeString()}.</h2>
                    </div>
                </>
            );
        };
        root.render(<App />);

    }
</script>
  • 分割代入
const Item = ({value}) => {
  • 分割代入(デフォルト値有)
const Item = ({value = 'hello'}) => {
  • 分割代入(デフォルト値有、変数のリネーム)
const Item = ({value: v = 'hello'}) => {
  • 関数を渡す。
  • boolを渡す。
  • オブジェクトを渡す。
  • split演算子(...foo)で渡す。
mskmsk

配列をmapしてコンポーネント生成

const ItemValues = ['Hello', 'World', 'React'];
ItemValues.map((value) => {
    const Item = (props) => {
        return (
            <li>{props.value}</li>
        );
    }
    root.render(<Item value={value} />);
});
mskmsk

値を保持するコンポーネント

  • React.useState()で定数名と操作する関数を返してくれる。constで宣言する。
const [count, setCount] = React.useState(0);
const decrement = () => {
    if(count > 0) {
        setCount(count - 1);
    }
};
const increment = () => setCount(count + 1);
<button onClick={decrement}>-</button>
<button onClick={increment}>+</button>

メモ:再レンダリングの条件はstate、propsが更新された時、親コンポーネントが再レンダリングされた時。

  • 連続して操作関数を呼び出す場合、非同期での呼び出しのため外から変数を渡すのではなく前回の値を保持する値を取り出して、そこに値の操作を行う。
setCount(count + 1);
setCount((previousCount) => previousCount + 1);
setCount((previousCount) => previousCount + 1);
mskmsk
const ItemValues = [
    {id: 0, name: 'Item1', value: 100},
    {id: 1, name: 'Item2', value: 150},
    {id: 2, name: 'Item3', value: 200},
];

const Item = (props) => {
    const increment = () => {
        props.onIncrement(props.id);
    }
    return (
        <li>
            {props.name} |
            {props.value}
            <button onClick={increment}>+</button>
        </li>
    );
};

const App = () => {
    const [counts, setCounts] = React.useState([0, 0, 0]);
    const increment = (id) => {
        const newCounts = [...counts];
        console.log(newCounts);
        newCounts[id] += 1;
        console.log(newCounts);
        setCounts(newCounts);
        console.log('increment');
    }

    const Items = () => {
        const itemValuesComponent = ItemValues.map((item) => {
            return (
                <Item 
                    key={item.id} 
                    id={item.id}
                    name={item.name} 
                    value={counts[item.id]}
                    onIncrement={increment}  />
            );
        })
        return itemValuesComponent;
    };
    return (
        <div>
            <h1>Shopping Cart</h1>
            <ul>
                <Items />
            </ul>
        </div>
    )
}
mskmsk

JavaSctriptの基礎

  • ブラウザでのデバック
    debuggerと記述するとブラウザでデバックできる。

  • import/export

    • export defaultの宣言はファイルに1つ
    • 最後にまとめてexportするのは名前付きexport
    • export defaultしたものをimportするには名前を付ける。{}は必要ない。
import foo from './foo.js'
  • typeだけをimportする場合
import type { foo } from './foo.js'
mskmsk

React Developer Tools

  • Components
    Componentのツリーを確認できる
    propsとしてわたってくるデータを確認できる。編集できる。
    ソースに飛ぶこともできる
    歯車アイコンから「Highlight updates when components render.」にチェックを入れると再レンダリングの個所が分かる。
  • Profiler
    レンダリングの内容と時間
mskmsk

検索テクニック

  • after:2024
  • site: or damain:
  • foo * baseのようにアスタリスク
mskmsk

TypeScript

  • プロジェクト作成
npx create-react-app project-name --template typescript
mskmsk
  • リテラル型
let hello: 'hello' = 'hello';

type DayOfWeek =
| 'Monday'
| 'Truesday'
※最初のパイプは無視される。

mskmsk

Type

  • 関数の型定義とは
Type FuncDefine = (x: number, y: number): number;
const func: FuncDefine = (x, y) => x + y;

関数の引数と戻り値の型定義のみを行える。

mskmsk

React.FC

  • Reactの関数コンポーネント(FunctionComponent)

React.ReactNode

  • propsに型定義
type FooProps = {
    name : string,
    children: React.ReactNode,
    fn: (text: string)  -> void
}
const Bar: React.FC<FooProps> = (props) => {
    return (
    <>
        <div>
            Hello {props.name} {props.children}
        </div>
    </>
)
}
mskmsk

Eventタイプ

  • React.ChangeEvent
  • React.MouseEvent

SynthetricEventを継承している。

mskmsk

useStateに型定義

type User{
    name: string,
    age: number
}
const [users, setUsers] = useState<User[]>([{name: "name1", age: 23}])