Front-End

vsoghlv@naver.com

React.js 타입스크립트에서 redux Thunk 사용2 컴포넌트 만들기

이전 포스트에 이어서 컴포넌트를 만든다.

프리젠테이셔널 컴포넌트

두개의 프리젠테이셔널컴포넌트를 만들건데 하나는 사용자의 계정 입력 후 조회 시 api 를 호출하는 컴포넌트와 받아온 정보를 그려주는 컴포넌트를 만들 것이다.

//components/GithubUsernameForm.tsx
import React, { ChangeEvent, FormEvent, useState } from "react";
import "./GithubUsername.css";

type GithubUsernameFormProps = {
  onSubmitUsername: (username: string) => void;
};

function GithubUsernameForm({ onSubmitUsername }: GithubUsernameFormProps) {
  const [input, setInput] = useState("");

  const onSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    onSubmitUsername(input);
  };
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    setInput(e.target.value);
  };

  return (
    <form onSubmit={onSubmit} className="GithubUsernameForm">
      <input type="text" onChange={onChange} value={input} />
      <button>조회</button>
    </form>
  );
}

export default GithubUsernameForm;


//components/GithubProfileInfo.tsx
import React from "react";
import "./GithubProfileInfo.css";

//받아올 props 타입지정
type GithubProfileInfoProps = {
  name: null;
  thumbnail: string;
  bio: null;
  blog: string;
};

function GithubProfileInfo({
  name,
  thumbnail,
  bio,
  blog,
}: GithubProfileInfoProps) {
  return (
    <div className="GithubProfileInfo">
      <div className="profile-head">
        <img src={thumbnail} alt="user thumbnail" />
        <div className="name">{name}</div>
      </div>
      <p>{bio}</p>
      {/* 블로그가 공백이 아닌경우 블로그 보여주기 */}
      <div>{blog !== "" && <a href={blog}>블로그</a>}</div>
    </div>
  );
}

export default GithubProfileInfo;

두 개의 프리젠테이셔널 컴포넌트를 만들었는데 props 로 받아오는 값들의 타입지정과 onChange, onSubmit 의 event 객체 타입 지정을 제외하고 크게 다른 점은 없다.

컨테이너 컴포넌트

//containers/GithubProfileLoader.tsx
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../modules";
import GithubUsernameForm from "../components/GithubUsernameForm";
import GithubProfileInfo from "../components/GithubProfileInfo";
import { getUserProfileThunk } from "../modules/github";

function GithubProfileLoader() {
  const { data, loading, error } = useSelector(
    (state: RootState) => state.github.userProfile
  );
  const dispatch = useDispatch();

  const onSubmitUsername = (username: string) => {
    dispatch(getUserProfileThunk(username));
  };

  return (
    <>
      <GithubUsernameForm onSubmitUsername={onSubmitUsername} />
      {loading && <p style=>로딩중..</p>}
      {error && <p style=>에러 발생!</p>}
      {data && (
        <GithubProfileInfo
          bio={data.bio}
          blog={data.blog}
          name={data.name}
          thumbnail={data.avatar_url}
        />
      )}
    </>
  );
}

export default GithubProfileLoader;