[react]第4週開発ログ


この文章はスパティンコードクラブ「フロントの花、反応」の3週間の講座を聞いて書いたものだ.

keyframes


:styled-コンポーネントに含まれるライブラリ.
  • 以上のアニメーションでよりダイナミックに動作を表現できます.
  • .box {
     width: 100px;
     height: 100px;
     background: #444;
    }
    .box.active {
     animation: boxFade 2s 1s infinite linear alternate;
    }
    @keyframes boxFade {
     0% {
      opacity: 1;
     }
     50% {
      opacity: 0;
     }
     100% {
      opacity: 1;
     }

    [Toy Project] BucketList

  • Progressbar
  • を追加
  • スクロールバー
  • を追加
  • CSSを修正し、よりきれいにします.
  • Progress.js
  • import React from "react";
    import styled from "styled-components";
    import { useSelector } from "react-redux";
    
    const Progress = (props) => {
      const bucket_list = useSelector((state) => state.bucket.list);
    
      let count = 0;
    
      let goal_per = bucket_list.map((l, idx) => {
        if (l.completed) {
          count++;
        }
      });
    
      return (
        <ProgressBar>
          <HighLight width={(count / bucket_list.length) * 100 + "%"}></HighLight>
          <Dot />
        </ProgressBar>
      );
    };
    const ProgressBar = styled.div`
      background: #eee;
      width: 100%;
      height: 20px;
      display: flex;
      border-radius: 10px;
      align-items: center;
    `;
    
    const HighLight = styled.div`
      background: #a566ff;
      width: ${(props) => props.width};
      height: 20px;
      border-radius: 10px;
      transition: 2s;
    `;
    
    const Dot = styled.div`
      background: #fff;
      border: 5px solid #a566ff;
      box-sizing: border-box;
      margin: 0px 0px 0px -10px;
      width: 40px;
      height: 40px;
      border-radius: 20px;
    `;
    export default Progress;
  • 結果画面
  • Firebase


    :リアルタイムデータベースのサービス提供
  • バックアップサービス:API形式でデータベース、ソーシャルサービス、ファイルシステムを提供

    FirebaseをReactにバインドする


    プロジェクトへのFirebaseの追加:糸にFirebaseを追加する
  • ./src/firebase.js
  • import firebase from "firebase/app";
    import "firebase/firestore";
    
    const firebaseConfig = {
        // firebase 설정과 관련된 개인 정보
    };
    
    firebase.initializeApp(firebaseConfig);
    
    const firestore = firebase.firestore();
    
    export { firestore };
    ➰コンポーネントDidMount()で値を追加、削除、および変更して、Cloud Firestoreの値が変更されたかどうかを決定します.
  • App.js
  •  ...
     componentDidMount() {
        const bucket = firestore.collection("bucket2");
    
        bucket.doc("bucket_item1").set({ text: "수영 배우기", completed: false });
    
        bucket
          .doc("bucket_item")
          .get()
          .then((doc) => {
            if (doc.exists) {
              console.log(doc);
              console.log(doc.data());
              console.log(doc.id);
            }
            console.log(doc.exists);
          });
    
        bucket.get().then((docs) => {
          let bucket_data = [];
    
          docs.forEach((doc) => {
            if (doc.exists) {
              bucket_data = [...bucket_data, { id: doc.id, ...doc.data() }];
            }
          });
    
          console.log(bucket_data);
        });
    
        // bucket.add({ text: "드럼 배우기", completed: false }).then((docRef) => {
        //   console.log(docRef);
        //   console.log(docRef.id);
        // });
    
        // bucket.doc("bucket_item").update({ text: "기타 배우기2" });
    
        bucket
          .doc("bucket_item2")
          .delete()
          .then((docRef) => {
            console.log("지웠어요!");
          });
      }
    ➰連動すると自動的にCloud Firestoreに値が入力され、以下のようになります.

    [HW] FriendTest

  • Progressbar
  • を追加
  • 若干css修正
  • Rankingページに自動スクロールを追加して私のランキング
  • にスクロールします.
  • Progress.js
  • import React from "react";
    import styled from "styled-components";
    import { useSelector } from "react-redux";
    
    const Progress = (props) => {
      const quiz_list = useSelector((state) => state.quiz.quiz);
      const answers = useSelector((state) => state.quiz.answers);
      let count = answers.length;
    
      return (
        <ProgressBar>
          <HighLight width={(count / quiz_list.length) * 100 + "%"}></HighLight>
          <Dot />
        </ProgressBar>
      );
    };
    
    const ProgressBar = styled.div`
      width: 80%;
      margin: 40px auto;
      margin-bottom: 80px;
      background: #eee;
      height: 20px;
      display: flex;
      align-items: center;
      border-radius: 10px;
    `;
    
    const HighLight = styled.div`
      background: #df402c88;
      width: ${(props) => props.width};
      height: 20px;
      border-radius: 10px;
      transition: width 1s;
    `;
    
    const Dot = styled.div`
      background: #fff;
      border: 5px solid #df402c88;
      box-sizing: border-box;
      margin: 0px 0px 0px -10px;
      width: 40px;
      height: 40px;
      border-radius: 20px;
    `;
    
    export default Progress;
  • Ranking.js
  • import React from "react";
    import styled from "styled-components";
    
    import { useSelector, useDispatch } from "react-redux";
    import { resetAnswer } from "./redux/modules/quiz";
    
    const Ranking = (props) => {
      const dispatch = useDispatch();
      const _ranking = useSelector((state) => state.rank.ranking);
    
      const user_rank = React.useRef(null);
    
      React.useEffect(() => {
        if (!user_rank) {
          return;
        }
    
        window.scrollTo({
          top: user_rank.current.offsetTop,
          left: 0,
          behavior: "smooth",
        });
      });
    
      const ranking = _ranking.sort((a, b) => {
        return b.score - a.score;
      });
    
      return (
        <RankContainer>
          <Topbar>
            <p>
              <span>{ranking.length}</span>의 사람들 중 당신은?
            </p>
          </Topbar>
    
          <RankWrap>
            {ranking.map((r, idx) => {
              if (r.current) {
                return (
                  <RankItem key={idx} highlight={true} ref={user_rank}>
                    <RankNum>{idx + 1}</RankNum>
                    <RankUser>
                      <p>
                        <b>{r.name}</b>
                      </p>
                      <p>{r.message}</p>
                    </RankUser>
                  </RankItem>
                );
              }
    
              return (
                <RankItem key={idx}>
                  <RankNum>{idx + 1}</RankNum>
                  <RankUser>
                    <p>
                      <b>{r.name}</b>
                    </p>
                    <p>{r.message}</p>
                  </RankUser>
                </RankItem>
              );
            })}
          </RankWrap>
    
          <Button
            onClick={() => {
              dispatch(resetAnswer());
              window.location.href = "/";
            }}
          >
            다시 하기
          </Button>
        </RankContainer>
      );
    };
  • 結果