Youtubeの実装を試みる-1



はんのう挑戦記


Youtube APIを受け入れて自分のYoutubeを作りましょう

人気ビデオapiのインポート


自分のyoutubeのメイン画面に表示されるビデオリストが必要です.親切に言って、私たちのyoutubeは無料で提供されているので、簡単に手に入れることができます.
まずfetchを呼びましょう
後でメンテナンスしやすいように、まずはYouTubeを選びます.jsという名前のファイルを作成し、すべてのapiをロードします.
APIキー値は非表示なので、個別に作成してロードします.
class Youtube{
	constructor(key){
    	this.key = key;
        this.getRequestOptions = {
        	method : "GET",
            redirect : "follow",
     };
    }
    
    async mostPopular(){
    	const response = await fetch(
      `https://youtube.googleapis.com/youtube/v3/videos?part=snippet&part=contentDetails&part=player&chart=mostPopular&maxResults=25&key=${this.key}`,
      this.getRequestOptions
    )
    const result = await response.json();
    return result.items;
  }
}

export default Youtube;
だからindexjsでは、
import Youtube from "./service/youtube";

const youtube = new Youtube(process.env.REACT_APP_YOUTUBE_API_KEY);

ReactDOM.render(
  <React.StrictMode>
    <App youtube={youtube} />
  </React.StrictMode>,
  document.getElementById("root")
);
ユーチューブという名前のクラスをインポートし、ステータス値をAppに送信します.
App.jsxでは、useEffectを使用してyoutubeをpropsとして受信し、コンポーネントをレンダリングするたびに特定の操作を実行します.mostpopular()関数を実行します.すでに実行されている場合は、ビデオで結果値が取得されます.
import React, { useState, useEffect } from "react";

const App = ({ youtube }) => {
  const [videos, setVideos] = useState([]);

  useEffect(() => {
    youtube.mostPopular().then((videos) => setVideos(videos));
  }, []);

  console.log(videos);

  return (
    <>
      <div>리액트 드럽게 어렵네.</div>
    </>
  );
};

export default App;

このようなビデオリストが届いたことを確認できます.
個人的にはfetchよりaxiosライブラリの方が使いやすいと思うのでaxiosを適用してみます
axiosの利点は次のとおりです.
ほとんどのブラウザはIEをサポートしています.(旧式を含む)
JSONデータを自動変換します.(不要.json()
...などなど.
axiosを使用するとbaseURL、Paramsを簡単に定義できます.
const httpClient = axios.create({
	baseURL : "https://youtube.googleapis.com/youtube/v3",
    params : { key: process.env.REACT_APP_YOUTUBE_API_KEY },
    });
    
// 받은 httpClient를 yotubue의 인자로 보내준다.
const youtube = new Youtube(httpClient)

ReactDOM.render(
  <React.StrictMode>
    <App youtube={youtube} />
  </React.StrictMode>,
  document.getElementById("root")
);
class Youtube{
	constructor(httpClient){
    	this.youtube = httpClient
    }
    
    async mostPoular(){
    	const response = await this.youtube.get('videos', {
        	params : {
            	part : "snippet",
                chart : "mostPopular",
                maxResult : 25,
        }
    }
    return response.data.items;
}

export default Youtube
このように既存のyoutubeクラスからデータをロードすることは、より直感的で便利になります.それでは他に必要なAPIもお呼びくださいあと2つのsearchとchannelが必要です.
その前に、mostpopularで、snippetではなくPartから2つの情報をロードしました.
 part: "snippet, contentDetails",

検索apiのインポート


次に,search機能を実現するためにsearch APIをロードする.
さっきのYouTubeにある
// 검색어(query)를 받아서 기존의 item data에 새로운 videoid값을 부여

async search(query){
	const response = await.this.youtube.get('search, {
    	params:{
        	part : "snippet",
            maxResults : 25,
            type : "video",
            q : query,
            },
        });
        return reponse.data.items.map((item) => ({
        	...item,
            id: item.id.videoId,
        }));
}
        
そしてappjsxでは、
  import React, { useState, useEffect } from "react";
import Nav from "./components/search/nav";

const App = ({ youtube }) => {
  const [videos, setVideos] = useState([]);

// Nav에서 검색어(query)를 받아서 다시 그걸 youtube 인자로 전달
  const search = (query) => {
    youtube
      .search(query) //
      .then((videos) => {
        setVideos(videos);
      });
  };

  useEffect(() => {
    youtube
      .mostPopular() //
      .then((videos) => setVideos(videos));
  }, [youtube]);

  console.log(videos);

  return (
    <>
      <Nav onSearch={search}></Nav>
      <div>진튜브</div>
    </>
  );
};

export default App;
Nav構成部品の作成を開始します.
onClick、onKeyPress関数を使用して入力します.valueを受け入れて再
アプリケーションにonSearchを呼び出して渡します.
const Nav = ({ onSearch }) => {
  const inputRef = useRef();
  const handleSearch = () => {
    const value = inputRef.current.value;
    onSearch(value);
  };

  const onClick = () => {
    handleSearch();
  };

  const onKeyPress = (event) => {
    if (event.key === "Enter") {
      handleSearch();
    }
  };

  return (
    <ul className={styles.nav}>
      <li className={styles.nav_left}>
        <ul className={styles.menu_part}>
          <li>
            <i className={`fas fa-bars ${styles.bar}`}></i>
          </li>
          <li>
            <img src={Logo} alt="logo" className={styles.logo} />
          </li>
          <li>
            <form action="">
              <input
                type="text"
                className={styles.search_bar}
                maxLength="30"
                ref={inputRef}
                onKeyPress={onKeyPress}
              ></input>
              <button className={styles.search_btn} onClick=						{onClick}>
                <i className="fas fa-search"></i>
              </button>
            </form>
          </li>
        </ul>
      </li>
      <li className={styles.nav_right}>
        <ul className={styles.profile_icons}>
          <li>
            <i className="far fa-caret-square-up"></i>
          </li>
          <li>
            <i className="fas fa-th-large"></i>
          </li>
          <li>
            <i className="far fa-bell"></i>
          </li>
          <li>
            <i className="far fa-user-circle"></i>
          </li>
        </ul>
      </li>
    </ul>
  );
};

export default Nav;
うん.何の間違いもないようです.キーとキーを押すたびに更新され、結果値は表示されません.あ….formが追加されたのか、リフレッシュされました.だからformを楽に消して

useCallback, memo


次にonClickとkeyPressという関数を宣言し、このように宣言すると、構成部品を再レンダリングするたびに関数が再作成されます.これは問題ありませんが、memo、useCallbackを使用して、頻繁にレンダリングされたり、構成部品が多い場合に最適化します.方法が簡単すぎる.
 const search = useCallback(
    (query) => {
      youtube
        .search(query) //
        .then((videos) => {
          setVideos(videos);
        });
    },
    [youtube]
  );
useCallbackの最初のパラメータに生成したい関数を加え、2番目のパラメータに依存値の配列を加えます.useCallbackはコールバックのコールバック済みバージョンを返します.これは、コールバックの依存性が変更された場合にのみ、コールバックのコールバック済みバージョンが変更されることを意味します.難しいですね.簡単に言えば、以前作成した関数を保存して再使用します.また、関数内部に依存する状態値がある場合は、2番目のパラメータ配列に明記する必要があります.
そしてmemoを利用して...
まず、ここでMemoを使用する理由について説明すると、Reactはまず構成部品をレンダリングし、その後、以前のレンダリング結果と比較してDOM更新を決定し、レンダリング結果が以前と異なる場合はDOMを更新する.この原理の下で動作するreact速度は非常に速いが,ここではさらに速度を向上させることができ,これはメモを書くことである.構成部品がmemoにカプセル化されると、構成部品は結果をレンダリングして記憶します.次に、次のレンダリングが発生したときにpropsが去った場合、reactionは記憶の内容を再使用します.
だから、やり方は以下の通りです.メモで包むだけでいいです.

import React, { useRef, memo } from "react";
import styles from "./nav.module.css";
// import { Link } from "react-router-dom";

const Nav = memo(({ onSearch }) => {

...code}

)
part 2にリストを作成する