Final project - Dev8


MusicPlayer


Reduxのロジックもある程度整理されています.
今日はVisualizerページで私が担当している音楽再生機能を正式に実現しました.

PlayList state redoxの適用


まず,練習の観点から,このページに必要なstateをReduxに適用する.
PlayList(オブジェクトが要素の配列として)はinitialstateに格納されます.
またreduceをしてルートreduceに登録しました.
その後、VisualizerコンポーネントはUserSelectorを使用してstateをインポートします.
const playList = useSelector(state => state.playListReducer);
入力したプレイリスト値は、現在再生中の曲のstateを表します.
crrentmusicという名前の状態で初期値を保存しました.
useStateとして保存されます.
const [crrentMusic, setCrrentMusic] = useState(playList[0]);
ReduxはなぜusStateを使用しなければならないのですか?
前述したように、グローバル位置で複数の素子に使用されるstateではありません.
Visualizerコンポーネントでのみ使用されるため、UserStateを使用しています.

state値レンダリングを受け入れる


CRRENTMusicに保存されている歌名、アーティスト名、歌詞、アルバムジャケットなどの価値を表現しています.
プレイリストにはすべてのリストがリストされている必要がありますので、プレイリストステータスを使用できます.
さらに素子を記述し,map関数を用いてpropsにそれぞれ値を渡す.
また、対応するリストをクリックするとcrrentmusicが変わります.
state liftingを用いてset関数をHandler関数で包みpropsに渡した.
<div className='play-list-box'>
   <ul className='play-list'>
      {
        playList.map((el, idx) => {
        return <PlayList key={idx} num={idx} music={el} handleChangeMusic={handleChangeMusic} />;
        })
      }
   </ul>
</div>

前の曲と次の曲のボタン機能を実現

react-h5-audio-playerには、showSkipControlsというUI/UX Propsが存在する.
これはよく使われる前の曲と次の曲のボタンで、ボタンだけが表示され、何の機能もありません.
逆に、onClickPreviousonClickNextのEventPropsがあります.onClickPreviousonClickNextの内部に論理が記述されている.

onClickNext


第一に、onClickNextはプレイリストの次の曲を再生します.
crrentMusicを抽出した値はプレイリストのいくつか目のインデックスであり、その値に+1を加算する.
現在の曲インデックス+1のインデックス値をsetCrrentMusicのパラメータとしてプレイリストに入れればよい.
 onClickNext={() => {
 	setCrrentMusic(playList[playList.indexOf(crrentMusic) + 1]);
 }
そうかと思ったが、まだ終わっていない.
歌ボタンを押し続けると、プレイリストの配列がインデックス値を超えます.
そのためエラーが発生しました.
そこで検証関数を作成し、通過時と通過時とを分けました.
function isValid (index) {
    if (!playList[index]) {
      return false;
    } else {
      return true;
    }
  }
まず、前述した論理計算に従って計算されたインデックスを検証関数でチェックします.
PlayListの長さから外れるとfalseが返され、逆も同様です.
検証結果がtrueの場合、前の論理に従って操作します.
falseはプレイリストの末尾なので、最初の曲を再生しました.
修正されたコード
 onClickNext={() => {
    if (isValid(playList.indexOf(crrentMusic) + 1)) {
   		setCrrentMusic(playList[playList.indexOf(crrentMusic) + 1]);
    }else {
        setCrrentMusic(playList[0]);
    }
 }
これはonEndedにも適用されます.

onClickPrevious


これは前に説明した論理とは逆である.
crrentMusicを抽出した値はプレイリストのいくつか目のインデックスであり、その値に-1を加算する.
計算されたインデックスが検証関数によってチェックされ、trueの場合
PlayListは、現在の楽曲インデックス-1のインデックス値をsetCrrentMusicのパラメータとする.
false綿プレイリストのエンディング曲が流れました.
onClickPrevious={() => {
    if (isValid(playList.indexOf(crrentMusic) - 1)) {
    	setCrrentMusic(playList[playList.indexOf(crrentMusic) - 1]);
    } else {
        setCrrentMusic(playList[playList.length - 1]);
    }
}

ランダム再生

react-h5-audio-playerに備わるべきものはすべて備わっていると思いますが、最も重要な機能が欠けているようです.
ランダム再生機能は、多くの人がストリーミングサービスを使用する際に使用しなければならない機能である可能性があります.
見つからなかったかどうかはわかりませんが、UI/UX PropsもEvent Propsもありません.
最終的には,ランダム再生はボタンを個別に作成して実現した.
現在crrentMusicはプレイリストのインデックス値です.
この場合、setCrentMusicのランダム値をパラメータとして使用して問題を解決できます.

Math.random()を使用してランダムな数値を作成するには


Math.randomは0から1まで数字の中で任意の数字を返します.
MDNの最大値を含む整数乱数の生成を参照してください.
最大整数を含む整数整数の作成
function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min; //최댓값도 포함, 최솟값도 포함
}
アノテーションによって作成された関数
function getRandomNumber (min, max) {
    return parseInt(Math.random() * ((Number(max) - Number(min)) + 1));
  }
ランダムにOnを再生した状態で、次の曲では、前の曲で上記の関数を使用してインデックス値を取得し、set関数に適用します.

ランダム再生を実現


まず,ランダム再生を押下したisRandom stateにboolean値を格納する.
ランダム再生ボタンを押すたびに、現在のboolean値の反対をset関数に変更します.onEndedonClickPreviousおよびonClickNextにおいて
論理はisRandomをtrueとfalseと区別することによって記述される.
isRandomがtrueの場合、getRandom Number関数に最小インデックス値、最大インデックス値を加え、ランダムな数値値を得てsetCrrentMusicの値とする.
onClickNext={() => {
   if (!isRandom) {
     if (isValid(playList.indexOf(crrentMusic) + 1)) {
       setCrrentMusic(playList[playList.indexOf(crrentMusic) + 1]);
     } else {
       setCrrentMusic(playList[0]);
     }
   } else {
       setCrrentMusic(playList[getRandomNumber(0, playList.length - 1)]);
   }
}}
ここで重要なのは、前の歌で何を聴いたかを覚えておくことです.
順番に再生するときはインデックス-1でいいので、
ランダムに再生する場合は順序性がないので、以前の音楽の空間を保存する必要があります.
配列を利用してstackアルゴリズムを実現する計画だ.

検出されたエラー


しばらくエンコードして、レンダリング画面を見るためにnpm runstartをしました.
しかし、次のエラーが発生しました.
Too many re-renders. React limits the number of renders to prevent an infinite loop.
レンダリングが多すぎますが、Reactは無限ループを防ぐためにレンダリング数を制限します.
これは、ランダム再生ボタンでonClickイベントに対して直ちに関数を実行したことによるエラーです.
<button onClick={setIsRandom(!isRandom)}>
   {isRandom?'현재 랜덤재생 ON':'현재 랜덤재생 OFF'}
</button>
Propsで渡された関数をCalbackで包むと、パフォーマンスの最適化に役立ちます.
set関数を関数内部で実行すると、エラーが消え、次のようになります.
<button onClick={() => { setIsRandom(!isRandom); }}>
  {isRandom?'현재 랜덤재생 ON':'현재 랜덤재생 OFF'}
</button>
ちょうど私を除いて、もう一人の隊員が同じ間違いに挿入しています.
すぐに学んだことを書きましたハハ

今日はここまで。


作成されたコードから見ると、これはかなり簡単な論理であり、長い時間をかけて考え、実現されています.
なんといっても2週間のプロジェクトでほぼバックグラウンドを担当していたのでフロントの感じが悪かったです.
知っていますが、忘れ方が多く、stateを扱うSenseもかなり下がっています.
Reduxも完全に私のものではないので、プロジェクトでも時間を割いて勉強の準備をしなければなりません.

コメントサイト


https://juhi.tistory.com/23
https://www.npmjs.com/package/react-h5-audio-player
https://velog.io/@ppby/Error
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math/random#%EB%91%90_%EA%B0%92_%EC%82%AC%EC%9D%B4%EC%9D%98_%EB%82%9C%EC%88%98_%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0
https://dasima.xyz/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-math-random-%EB%B2%94%EC%9C%84-%EC%9E%90%EB%A6%BF%EC%88%98/
https://velog.io/@mnmm/js-parseint-mathfloor