연습을 해봤어요.

68647 단어 ReactTypeScripttech

개시하다


리액트 헤주온 레닝은 올리일본에서 발간한 리액트의 해설서다.실제 작업에서 몇 달간 리액트만 사용했지만 수평감으로는 많은 수확이 있었다.
이 가운데 6장에서 시작하는 앱을 설치하면서 리액트 구성 요소를 팩스로 전송한다는 해설에서는 리액트 상급자가 코드의 질을 높이는 방법을 어떻게 생각하는지 다시 한번 체험할 수 있어 많은 것을 배웠다.
이 기사는 그 과정을 TypeScript화한 뒤 실제로 손으로 시도한 기록이다.총결산의 기술이기 때문에 조금이라도 흥미가 있는 사람은 반드시 손에 쥐고 스스로 해 보아야 한다.
https://www.amazon.co.jp/React한슨 학습-제2판-웹 응용 개발의 최적 실천-Alex-Banks/dp/487311933

차리다


다음과 같은 응용 프로그램을 만듭니다.

먼저 프로젝트를 만들어 스타가 될 수 있도록 하자.
npx create-react-app star-rating --template typescript
cd star-rating
필요 없는 파일을 삭제합니다.삭제된 디렉터리 구조는 다음과 같다
star-rating
├── README.md
├── node_modules
├── package.json
├── public
│   └ index.html
├── src
│   ├── App.tsx
│   └── index.tsx
└── yarn.lock
src/index.tsx는 다음과 같이 개작한다.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
별 모양 아이콘react-icons을 표시하기 위해 포장을 설치한다.
yarn add react-icons
디렉터리에 src 파일을 만들고 다음 코드를 기술합니다.
import { FaStar } from "react-icons/fa";

export default function StarRating() {
  return (
    <>
      <FaStar color="red" />
      <FaStar color="red" />
      <FaStar color="red" />
      <FaStar color="grey" />
      <FaStar color="grey" />
    </>
  );
}
StarRating.tsx를 다음과 같이 고쳤다.
import StartRating from "./StarRating";

export default function App() {
  return <StartRating />;
}
src/App.tsx 확인 결과.
다음과 같이 표시되면 성공합니다.
yarn startVScode에서 상기 오류가 발생한 경우 아래 글 등을 참고하여 VScode의 TypeScript 버전을 변경하십시오
https://qiita.com/tanaShoe/items/3a2f00f9f8906cb55101
하지만 지금은 SVG로 스타를 보여주는 것에 불과해 동적으로 디스플레이를 바꿀 수는 없다.다음 장에서는 상태를 관리하여 뷰를 동적으로 수정할 수 있습니다.

useState를 사용하여 클릭 이벤트 지원


선택한 별은 빨간색, 선택하지 않은 별은 회색으로 표시됩니다.
const Star = ({ selected = false }) => (
  <FaStar color={selected ? "red" : "gray"} />
)
등급은 5개 등급으로 평가가 많았다는 인상을 주는데 이번에 다음과 같은 처리를 추가해 별의 수량을 가변적으로 만들었다.따라서 단계별로 등급을 평가할 수 있는 구성 요소를 만듭니다.
export default function StarRating({ totalStarts = 5 }) {
  retrun [...Array(totalStarts)].map((_, i) => <Star key={i} /> );
}
useState를 사용하여 구성 요소에 상태를 추가합니다.최종Cannot use JSX unless the '--jsx' flag is provided은 다음과 같다.
src/StarRating.tsx
import { useState } from "react";
import { FaStar } from "react-icons/fa";

const Star = ({ selected = false }) => (
  <FaStar color={selected ? "red" : "gray"} />
);

export default function StarRating({ totalStars = 5 }) {
  const [selectedStars] = useState(3);
  return (
    <>
      {[...Array(totalStars)].map((n, i) => (
        <Star key={i} selected={selectedStars > i} />
      ))}
      <p>
        {selectedStars} of {totalStars} stars
      </p>
    </>
  );
}
이렇게 하면 StarRating.tsx 내의 초기값에 따라 비용율의 색깔이 동태적으로 변화할 수 있다.
useState의 값이 사용자의 클릭에 따라 달라질 수 있다면 스타의 색깔을 상호작용적으로 바꿀 수 있을 것이다.useState 내의 StarRating.tsx 함수를 다른 구성 요소로 분리하고 Star 이벤트 처리 프로그램을 설정합니다.
src/Star.tsx
import { FaStar } from "react-icons/fa";

const Star = ({ selected = false, onSelect = () => {} }) => (
  <FaStar color={selected ? "red" : "gray"} onClick={onSelect} />
);

export default Star;
onClick를 다음 내용으로 바꾸면 Star 구성 요소를 눌렀을 때state의 값이 변경됩니다.
src/StarRating.tsx
import { useState } from "react";
import Star from "./Star";

export default function StarRating({ totalStars = 5 }) {
  const [selectedStars, setSelectedStars] = useState(3);
  return (
    <>
      {[...Array(totalStars)].map((n, i) => (
        <Star
          key={i}
          selected={selectedStars > i}
          onSelect={() => setSelectedStars(i + 1)}
        />
      ))}
      <p>
        {selectedStars} of {totalStars} stars
      </p>
    </>
  );
}
클릭한 스타에 따라 state 값을 변경하고 StarRating 구성 요소를 다시 그립니다.다음은 스타 색깔의 상호작용 변화.

전체 애플리케이션 상태 관리


타구의 기본 기능을 추가했다.여기서 색상 정보 목록을 관리하는 색상 샘플 적용을 시작하여 각 색상에 대한 요율 값을 지정합니다.
이것을 어리석게 실현하려고 한다면, 많은 구성 요소들이state 값을 가진 프로그램이 될 것입니다.이것은 이상적인 상태가 아닌 것 같습니다. 복수가 있는 구성 요소가state가 있는 전화기는 추가와 디버깅이 어려워지는 부작용을 일으킬 수 있습니다.
이런 상황에서 한 곳에서 응용 프로그램의state를 관리하는 것이 더욱 효율적이다. 예를 들어 가장 높은 구성 요소는 모든state를 관리할 수 있다.state를 최상급 구성 요소에서 속성 값으로 서브 구성 요소로 전달하고 데이터를 전체 응용 프로그램에 반영하여state 관리를 간단하게 합니다.
먼저 애플리케이션에서 사용할 데이터를 준비합니다.
src/color-data.json
[
  {
    "id": "0175d1f0-a8c6-41bf-8d02-df5734d829a4",
    "title": "ocean at dusk",
    "color": "#00c4e2",
    "rating": 5
  },
  {
    "id": "83c7ba2f-7392-4d7d-9e23-35adbe186046",
    "title": "lawn",
    "color": "#26ac56",
    "rating": 3
  },
  {
    "id": "a11e3995-b0bd-4d58-8c48-5e49ae7f7f23",
    "title": "bright red",
    "color": "#ff0000",
    "rating": 0
  }
]
이번 프로그램은 루트 구성 요소 StarRating.tsx 를 통해 모든state를 관리할 것입니다.App 이외의 구성 요소는state가 없기 때문에 App를 사용하는 것도 useState 구성 요소뿐입니다.
아래와 같이 App 덮어쓰고 App.tsx 에서state 값을 읽고 다음 구성 요소에 건네줍니다.
src/App.tsx
import { useState } from "react";
import colorData from "./color-data.json";
import ColorList from "./ColorList.tsx";

export default function App() {
  const [colors] = useState(colorData);
  return <ColorList colors={colors} />;
}
color-data.json 아래에서 만듭니다src.
src/ColorList.tsx
import Color from "./Color";

type ColorProps = {
  id: string;
  title: string;
  color: string;
  rating: number;
};

export default function ColorList({ colors = [] }: { colors: ColorProps[] }) {
  if (!colors.length) return <div>No Colors Listed.</div>;

  return (
    <div>
      {colors.map((color) => (
        <Color key={color.id} {...color} />
      ))}
    </div>
  );
}
이 구성 요소는 부모 구성 요소 ColorList.tsx 에서 전달된 속성 App.tsx 에서 추출됩니다.배열 길이가 0이면 메시지가 표시됩니다.
만약 그룹이 데이터 colors 를 포함한다면, Array.map 색 정보를 구성 요소에 하나하나 전달합니다.Color 색상 정보를 표시하기 위해 구성 요소를 추가합니다.
src/Color.tsx
import StarRating from "./StarRating";

export default function Color({
  title,
  color,
  rating,
}: {
  title: string;
  color: string;
  rating: number;
}) {
  return (
    <section>
      <h1>{title}</h1>
      <div style={{ height: 50, backgroundColor: color }} />
      <StarRating selectedStars={rating} />
    </section>
  );
}

Color 구성 요소Color의 데이터를 속성 값으로 rating에 건네준다.StarRating.tsx 개작은 다음과 같다.
src/StarRating.tsx
import Star from "./Star";

export default function StarRating({ totalStars = 5, selectedStars = 0 }) {
  return (
    <>
      {[...Array(totalStars)].map((n, i) => (
        <Star key={i} selected={selectedStars > i} />
      ))}
      <p>
        {selectedStars} of {totalStars} stars
      </p>
    </>
  );
}
특히 이전에 실시된StarRating.tsx에 비해 이번 구성 요소는state의 값이 없다.state가 없는 함수 구성 요소를 순수 함수라고 하는데, 같은 속성 값을 얻으면 반드시 같은 결과를 그립니다.순함수는 테스트하기 쉽고 코드 전망도 좋아지는 장점이 있다.
이 실행에서 데이터를 그리는 결과는 다음과 같습니다.

어셈블리 트리 아래에서 사용자 작업 위로 전달


그러나 지금은 StarRating.tsx의 값만 표시되기 때문에 색상 정보를 평가하거나 삭제할 수 없습니다.
사용자의 작업은 끝에 있는 구성 요소에 대한 것입니다. 색 정보는state로 맨 위에 있는 color-data.json 구성 요소에 저장됩니다.정보를 동적으로 바꾸기 위해서는 사용자의 조작을 끝부분의 구성 요소에서 루트 구성 요소로 전달하여state의 값을 변화시켜야 한다.App 함수와 onRemove 함수를 추가하여state를 삭제하거나 업데이트할 수 있도록 합니다.
src/Color.tsx
import StarRating from "./StarRating";
import { FaTrash } from "react-icons/fa";

export default function Color({
  id,
  title,
  color,
  rating,
  onRemove = () => {},
  onRate = () => {},
}: {
  id: string;
  title: string;
  color: string;
  rating: number;
  onRemove: (id: string) => void;
  onRate: (id: string, rating: number) => void;
}) {
  return (
    <section>
      <div style={{ display: "flex", alignItems: "center" }}>
        <h1>{title}</h1>
        <button
          style={{ height: 36, marginLeft: 10 }}
          onClick={() => onRemove(id)}
        >
          <FaTrash />
        </button>
      </div>
      <div style={{ height: 50, backgroundColor: color }} />
      <StarRating
        selectedStars={rating}
        onRate={(rating: number) => onRate(id, rating)}
      />
    </section>
  );
}
onRate 요소<button>를 추가하여 이벤트 처리 프로그램을 설정합니다.버튼을 누르면onClick 함수에 불이 나고 Color 구성 요소 자체가 처리 내용에 전혀 민감하지 않습니다.부모 구성 요소에 이벤트를 알리기만 하면 구성 요소는 순수 함수로 유지됩니다.onRemove도 마찬가지다.
src/ColorList.tsx
import Color from "./Color";

type ColorProps = {
  id: string;
  title: string;
  color: string;
  rating: number;
};

export default function ColorList({
  colors = [],
  onRemoveColor = () => {},
  onRateColor = () => {}
}: {
  colors: ColorProps[],
  onRemoveColor: (id: string) => void,
  onRateColor: (id: string, rating: number) => void,
}) {
  if (!colors.length) return <div>No Colors Listed. (Add a Color)</div>;

  return (
    <div>
      {colors.map(color => (
        <Color
          key={color.id}
          {...color}
          onRemove={onRemoveColor}
          onRate={onRateColor}
        />
      ))}
    </div>
  );
}
마지막ColorList.tsx은 다음과 같다.
src/App.tsx
import { useState } from "react";
import colorData from "./color-data.json";
import ColorList from "./ColorList";

export default function App() {
  const [colors, setColors] = useState(colorData);
  return (
    <ColorList
      colors={colors}
      onRateColor={(id, rating) => {
        const newColors = colors.map((color) =>
          color.id === id ? { ...color, rating } : color
        );
        setColors(newColors);
      }}
      onRemoveColor={(id) => {
        const newColors = colors.filter((color) => color.id !== id);
        setColors(newColors);
      }}
    />
  );
}
App.tsx에서 하위 구성 요소로부터 알림을 받아state 값을 바꾸는 처리를 합니다.결과적으로 루트 구성 요소 하나만state를 관리하면 응용 프로그램을 실현할 수 있습니다.onRateColor``onRemoveColor에 함수StarRating.tsx를 추가하고 사용자의 조작을 모듈에 알립니다.
src/StarRating.tsx
import Star from "./Star";

export default function StarRating({
  totalStars = 5,
  selectedStars = 0,
  onRate = () => {},
}: {
  totalStars?: number;
  selectedStars: number;
  onRate: (num: number) => void;
}) {
  return (
    <>
      {[...Array(totalStars)].map((n, i) => (
        <Star
          key={i}
          selected={selectedStars > i}
          onSelect={() => onRate(i + 1)}
        />
      ))}
      <p>
        {selectedStars} of {totalStars} stars
      </p>
    </>
  );
}
아래처럼 이렇게 일을 할 수 있다면 성공할 것이다

끝말


React Hazuon Launing에서는 여기서부터 앱을 더 확장해 팩스 조작을 하고, 코드의 질을 높이는 동시에 실장한다.
나는 이것이 매우 이해하기 쉬운 해설서로 초급부터 고급까지 많은 엔지니어들에게 추천할 수 있다고 생각한다.관심 있는 사람은 꼭 구해보세요.

좋은 웹페이지 즐겨찾기