React*Type Script*Material-II에서 유튜브의 댓글창에 상징적인 UI를 만드는 방법

react_mui_comment_list_mock


개시하다


이 보도에 관하여


리액트와 머티리얼즈-II를 이용해 유튜브 리뷰 막대의 직접 UI를 만드는 방법을 소개한다.

그림 완성


画像

전제 조건


사용할 데이터 정보


실제 개발에서는'기고'와'사용자'의 대상을 별도의 표로 만들어 DB에서 관리하는 경우가 많다.
이번에는 API 서버에서 데이터를 가져오는 상황을 구상합니다.
'투고'를 의미하는 데이터'포스트'의 json 배열,
"사용자"를 의미하는 데이터를 사용한 "User"의 json 배열을 사용한 후 UI를 조립해 보려고 합니다.
ここにER図を入れる

컨디션

  • React
  • [email protected]
  • node
  • v14.17.4
  • yarn
  • 1.22.11
  • Typescript
  • [email protected]
  • Material-UI
  • v4.0
  • MomentJS
  • [email protected]
  • 요점


    JavaSciept의 Aray 객체에 대한 두 가지 방법을 사용하여 User 배열과 Post 배열용 키 항목을 결합합니다.
  • Array.prototype.map()
  • Array.prototype.find()
  • 코드 예
    ....
    {posts?.map((post) => {
              const found = users?.find((user) => post.user_id === user.id);
    ....
    

    디테일


    ① React 애플리케이션 제작


    우선 리액트 앱을 만들어보자.
    $ npx create-react-app test --template=typescript
    

    ② yarn에서 포장 받기


    사과 제작이 완료되면 야른으로 포장을 받으세요.
    $ yarn add @material-ui/core @material-ui/icons moment
    $ yarn start
    

    ③ 데이터 파일 제작


    '투고' 와 '사용자' 를 나타내는 데이터 파일을 만듭시다.
    src/data.ts
    export const postData = [
      {
        id: 1,
        user_id: 2,
        message: '1コメゲットです。',
        created_at: '2021-09-21T01:42:13.094Z',
      },
      {
        id: 2,
        user_id: 1,
        message: '惜しくも2コメとなりました。',
        created_at: '2021-09-22T01:42:13.094Z',
      },
    ];
    
    export const userData = [
      {
        id: 1,
        name: '山田太郎',
      },
      {
        id: 2,
        name: '花子山田',
      },
    ];
    

    ④ presentational component 제작

  • Post 구성 요소
    개별 포스트를 표현하는 어셈블리를 만듭니다.
    PostList 어셈블리에서 proops를 수신하여 Post를 렌더링하는 데 사용되는 어셈블리입니다.
    모멘텀JS를 사용해'몇 초 전','몇 분 전'등의 발언 시간을 표시했다.
  • src/Post.tsx
    import { VFC } from "react";
    
    // MomentJSをインポートし、localeをjaに設定する
    import moment from "moment";
    import "moment/locale/ja";
    
    import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
    import ListItem from "@material-ui/core/ListItem";
    import Divider from "@material-ui/core/Divider";
    import ListItemText from "@material-ui/core/ListItemText";
    import Typography from "@material-ui/core/Typography";
    import { Avatar, ListItemAvatar } from "@material-ui/core";
    import ThumbUpIcon from "@material-ui/icons/ThumbUp";
    import ThumbDownIcon from "@material-ui/icons/ThumbDown";
    
    const useStyles = makeStyles((theme: Theme) =>
      createStyles({
        inline: {
          display: "inline",
        },
        margin: {
          margin: theme.spacing(1, 1, 0, 2),
        },
      })
    );
    
    type Props = {
      key: number;
      name: string;
      message: string;
      created_at: string;
    };
    
    const Post: VFC<Props> = (props) => {
      const classes = useStyles();
      const { key, name, message, created_at } = props;
    
      return (
        <div>
          <>
            <ListItem alignItems="flex-start" key={key}>
              <ListItemAvatar>
                <Avatar alt="" />
              </ListItemAvatar>
              <ListItemText
                primary={
                  <>
                    <Typography
                      component="span"
                      variant="body2"
                      className={classes.inline}
                      color="textPrimary"
                    >
                      {name}
                    </Typography>
                    <Typography
                      component="span"
                      variant="body2"
                      className={classes.inline}
                      color="textSecondary"
                    >
                       {moment(created_at).fromNow()}
                    </Typography>
                  </>
                }
                secondary={
                  <>
                    <Typography
                      component="span"
                      variant="body1"
                      className={classes.inline}
                      color="textPrimary"
                    >
                      {message}
                    </Typography>
                    <br />
                    返信
                    <ThumbUpIcon
                      className={classes.margin}
                      color="disabled"
                      fontSize="small"
                    />
                    <ThumbDownIcon
                      className={classes.margin}
                      color="disabled"
                      fontSize="small"
                    />
                  </>
                }
              />
            </ListItem>
            <Divider variant="inset" component="li" />
          </>
        </div>
      );
    };
    
    export default Post;
    
  • PostList 구성 요소
    포스트 차트를 나타내는 어셈블리를 생성합니다.
    data.ts에서 json 배열, 포스트를 가져옵니다.tsx에 전달하여 Post의 일람표를 재현합니다.
    포스터의 맵 방법과 users에 대한find 방법을 조합하여
    postData 내 사용자id와 userData 내의 id가 결합되어 있습니다.
  • src/PostList.tsx
    import { VFC } from "react";
    import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
    import List from "@material-ui/core/List";
    
    import Post from "./Post";
    import { postData, userData } from "./data";
    
    const useStyles = makeStyles((theme: Theme) =>
      createStyles({
        root: {
          width: "25vw",
        },
        txt: {
          margin: theme.spacing(2),
        },
      })
    );
    
    type PostData = {
      id: number;
      user_id: number;
      message: string;
      created_at: string;
    };
    
    type User = {
      id: number;
      name: string;
    };
    
    const PostList: VFC = () => {
      const classes = useStyles();
      const posts: PostData[] = postData;
      const users: User[] = userData;
    
      return (
        <div>
          <List className={classes.root}>
            {posts?.map((post) => {
              const found = users?.find((user) => post.user_id === user.id);
              return (
                <Post
                  key={post.id}
                  name={found?.name as string}
                  message={post.message}
                  created_at={post.created_at}
                />
              );
            })}
          </List>
        </div>
      );
    };
    
    export default PostList;
    
  • App 구성 요소
    마지막으로 앱.tsx에 조립합니다.
  • src/App.tsx
    import "./App.css";
    
    import { VFC } from "react";
    import PostList from "./PostList";
    
    const App: VFC = () => {
      return (
        <div className="App">
          <PostList />
        </div>
      );
    };
    
    export default App;
    
    

    ⑤ 확인


    실제로 모니터를 해보니까...
    user_id가 1인post, id가 1인user의name에 링크
    user_나는 id가 2에 대한post라고 생각한다. id는 2의user의name가 연결되어 있음을 확인할 수 있다.
    チェック

    끝말


    끝까지 읽어주셔서 감사합니다.
    이번 기사에서는 리액트와 머티리얼즈-II를 활용해 유튜브의 게시판에 실제 UI를 표시하는 방법에 대해 해설했다.
    CSS, 답장 버튼, Good/Bard 버튼 등을 적절하게 조정하십시오. 논리를 구현하여 더욱 실용적인 UI로 사용할 수 있도록 하겠습니다.
    이번에 사용한 코드는 여기.에 저장됩니다.
    자유롭게 사용하세요.

    좋은 웹페이지 즐겨찾기