⚛️ 反応+タイプ101🥡


บันทึกความเข้าใจจาก


React ไปวันๆ EP.4 - Typescript in React 101

タイで反応する / RETS - TS - 101


สิ่งที่ควรต้องรู้ในการเขียน 反応するด้วย タイプスクリプト


このプロジェクトはブートしたCreate React App .

目的


このプロジェクトは、より多くのコードを書くためにJavaScriptからTypesScriptにアップスキルをしたい人のために設計されています.
ちょうどTypesScriptを使用し始めた人々のためにお勧め!

貢献


お気軽にPRまたは連絡先を送信するsiriwat あなたがより素晴らしい考えを持っているならば.
View on GitHub

トピック

  • UseState
  • Promise
  • Chidren Types
  • Compound Component
  • Bye Bye Enum
  • React & html type that you should know
  • CSS type
  • なぜタイプスクリプト


    เมื่อก่อน ジャバスクリプトถูกก デザインให้ใช้งานง่ายๆสำหรับ ブラウアーแต่ตอนนี้มันอยู่ทุกส่วนแล้ว

    種類


    เหมือน インターフェースแต่สามารถกำหนดชื่อให้ プリミティブ型ได้ ใช้ในรูป 労働組合ได้ ในรูป タプルได้

    Tuple คืออะไร
    Tuple เป็น Data Structure แบบหนึ่งที่เป็น Array แบบ Fixed Size โดยที่ Data ที่อยู่ภายใน Tuple ไม่จำเป็นต้องเป็น Type ชนิดเดียวกัน

    unions คืออะไร ดูข้างล่างนี้


    type User = {
      firstname: string;
      lastname: string;
    };
    type NumberOrStringOrStudent = string | number | User;
    
    let myValue: NumberOrStringOrStudent;
    const sampleUser: User = {
      firstname: "Sippakorn",
      lastname: "Raksakiart",
    };
    
    // ประกาศ Tuple
    let option: [string, boolean, number];
    
    option = ["uppercase", true, 1]; // OK
    option2 = [false, 2, "lowercase"]; // ERROR
    

    米国不動産

    export type ProfileProps = {
      name: string,
      age: number,
    };
    // todo: create Prop type for this component, also optional type
    export function BasicProps({ name, age }: ProfileProps) {
      return (
        <div>
          <div>Name: {name}</div>
          <div>Age: {age}</div>
        </div>
      );
    }
    

    ถ้าอยากได้แบบ optional ละก็เพิ่ม ?

    export type ProfileProps = {
      name?: string,
      age?: number,
    };
    
    const [boolOrNum, setBoolOrNum] = useState();
    const [boolOrNum, setBoolOrNum] = useState<boolean | number>(); // need to be boolean | number
    
    <button
      onClick={() =>
        setBoolOrNum((c) => {
          if (typeof c === "number") {
            return c + 1;
          }
        })
      }
    >
      Increment
    </button>;
    

    อย่าลืมที่จะใส่ Item[]

    
    interface Item {
      id: string
      name: string
    }
    
    export function Example2() {
      const [data, setData] = useState<Item[]>([]);
    
      return data.map((item, i) => (
        <div>
          Item {i} is {item.id}
        </div>
      ));
    }
    

    約束

    ดูนาทีที่ 45.00

    import React, { useEffect, useState } from "react";
    import { getData } from "../js/api";
    
    const api = (id: string) => new Promise<string>((resolve, reject) => {});
    
    // todo : create custom hook that set response from api to state and return the state
    function useData(id: number) {
      const [data, setData] = useState<number>();
      useEffect(() => {
        (async function () {
          setData(await getData(id));
        })();
      }, [id]);
      return data;
    }
    
    // what if api dont have type?
    

    จากข้างบนเราจะไม่รู้ว่า getData เป็น type อะไร เราอาจจะใส่ type ให้มันด้วยก็ได้
    หรือไม่ก็ได้เพราะ reusult ออกไปก็ถูกต้องอยู่ดี

    เข้าไปดู React.ReactNode

    type ReactChild = ReactElement | ReactText;
    
    type ReactNode =
      | ReactChild
      | ReactFragment
      | ReactPortal
      | boolean
      | null
      | undefined;
    
    interface ReactElement<
      P = any,
      T extends string | JSXElementConstructor<any> =
        | string
        | JSXElementConstructor<any>
    > {
      type: T;
      props: P;
      key: Key | null;
    }
    

    เข้าไปดู PropsWithChildren (นาที52)

    type PropsWithChildren<P> = P & { children?: ReactNode };
    

    หรือเราจะเขียน render prop

    import React from "react";
    
    type Props = {
      header: React.ReactNode; // can react  Children
      sidebar: React.ReactElement; // jsx
      footer: string;
      render: (value: boolean) => React.ReactNode;
    };
    
    export function Example({
      header,
      sidebar,
      footer,
      children,
    }: React.PropsWithChildren<Props>) {
      const [state, setState] = useState(false);
      return (
        <div>
          <header>{header}</header>
          <div>{sidebar}</div>
          <div>{children}</div>
          <footer>{footer}</footer>
          {render(state)}
        </div>
      );
    }
    

    複合成分

    มาดูกันว่าแบบนี้จะเขียน type ได้อย่างไร

    // Grid.tsx
    import React from "react";
    
    // todo : create Grid component that contain Row & Column
    
    // outside
    function App() {
      return (
        <Grid.Row>
          <Grid.Column>
            <div>Content 1</div>
          </Grid.Column>
          <Grid.Column>
            <div>Content 2</div>
          </Grid.Column>
        </Grid.Row>
      );
    }
    

    เพิ่มอันนี้เข้าไป

    const Grid = ({ children }: React.PropsWithChildren<{}>) => {
      return <div>{children}</div>;
    };
    
    const Row = ({ children }: React.PropsWithChildren<{}>) => {
      return <div>{children}</div>;
    };
    
    const Column = ({ children }: React.PropsWithChildren<{}>) => {
      return <div>{children}</div>;
    };
    
    // อย่าลืมที่ขะบอกว่า Row อยู่ใน Grid
    Grid.Row = Row;
    Grid.Column = Column;
    

    หรือจะทำแบบนี้แทนก็ได้ (นาทที่1hr.02 ผมเองก็ยังไม่เข้าใจจุดนี้)

    interface Grid {
      ({ children }: React.PropsWithChildren<{}>): React.ReactNode;
      Row: typeof Row;
      Column: typeof Column;
    }
    
    const Grid: Grid = () => {
      return <div />;
    };
    

    バイバイenum

    นาทีที่ 1hr.04

    import React from "react";
    
    enum Colors {
      Red = "red",
      Blue = "blue",
      Green = "green",
      White = "white",
    }
    
    type Props = {
      color: Colors;
    };
    

    นอกจากนี้ท่าที่ทำไม่ได้

    cons c1:Color = 'red'
    //ต้องใช้ท่านี้
    const c1 = 'red' as Colors
    
    

    หรือจะทำเป็น Object

    const Colors = {
     Red: 'red'
     Blue: 'blue'
    }
    
    type Prop ={
     color:Colors   // มันจะ error บอกว่าเอา Object มาทำ Type ไม่ได้
    }
    
    

    ต้องแปลง Object เป็น type

    const Colors = {
     Red: 'red'
     Blue: 'blue'
    }
    //typeof Colors = (typeof Colors) // ได้ struct Colors ละ
    typeof Colors = (typeof Colors)[keyof typeof Colors] //return key
    
    

    code จะใช้ได้เหมือน enum

    const Colors = {
      Red: "red",
      Blue: "blue",
    } as const;
    
    type Colors = typeof Colors[keyof typeof Colors];
    
    type Props = {
      color: Colors;
    };
    

    เราสามารถทำง่ายกว่านี้โดยใช้ enum

    const Colors = {
      Red: "red",
      Blue: "blue",
    } as const;
    type Enum<T> = T[keyof T];
    type Colors = Enum<typeof Colors>;
    
    type Props = {
      color: Colors;
    };
    
    ต่อจากนี้จะเป็น part 2

    ⚛️ React ไปวันๆ EP.5 - Typescript in React 101 part 2

    あなたが知っておくべき反応とHTMLタイプ


    ลองดูตัวอย่างต่อไปนี้ที่จำทำให้ カーソルไป フォーカスที่ 入力
    import React, { useRef, useEffect } from "react";
    
    // todo : create input that will be focused if autoFocus prop is true
    function Example({ autoFocus }: { autoFocus?: boolean }) {
      const inputRef = useRef();
      useEffect(() => {
        inputRef.current.focus();
      }, []);
      return (
        <form>
          <label htmlFor="input">Label</label>
          <input id="input" ref={inputRef} />
        </form>
      );
    }
    
    แต่มันยังผิดอยู่ต้องเพิ่ม HtmlInputElement เพิ่ม オプトラインオートให้ด้วย
    import React, { useRef, useEffect } from "react";
    
    // todo : create input that will be focused if autoFocus prop is true
    function Example({ autoFocus }: { autoFocus?: boolean }) {
      const inputRef = useRef<HTMLInputElement>(null);
      useEffect(() => {
        inputRef.current?.focus();
      }, [autoFocus ]);
      return (
        <form>
          <label htmlFor="input">Label</label>
          <input id="input" ref={inputRef} />
        </form>
      );
    }
    

    ค่อยมาเขียนต่อเนื่องจากเนื้อหาเริ่มจะซับซ้อนขึ้น ผมยังไม่เข้าใขพ 🥡