[Mini Project] Monster - Class

24500 ワード

機能と学習理念


動的ルーティングの使用
[メモリカード]をクリックすると、そのカードの[詳細]ページに移動します.
𕼧移動すると、前のページのBackBtnに直接移動できます.
✅ PrevPros

简単に考えてみよう!!


1.カードをクリックすると、カードの詳細ページに移動します。


2.移動後、前のページのBackBtnに直接移動できます


3. Card Prev Btn , Next Btn !!


動的ルーティングを有効にする(移動する必要があるため!!)


---Route.js-----
  <Router>
        <Switch>
          <Route exact path="/monsters" component={UrlParameters} />
          <Route exact path="/monsters/detail/" component={MonsterDetail} />
          <Route exact path="/monsters/detail/:id" component={MonsterDetail} />
        </Switch>
      </Router>

ルーティングを使用するには、デフォルトでパスを設定する必要があります。

  • <Route <Route exact path="/monsters" component={UrlParameters} />ではexceptive pathが正しい経路を示し、componentは移動する素子を記述すればよい.

  • 簡単に言えば、対応する経路に行けば、対応する素子に移動!!
  • カードにはルータが別途設置されていません!

      render() {
        const {id, name, email} = this.props;
        console.log(this.props.id);
        return (
          <div className="card-container" onClick={this.goToDetail}>
            <img src={`https://robohash.org/${id}?set=set2&size=180x180`}></img>
            <h2> {name}</h2>
            <p> {email}</p>
          </div>
        );
      }
      export default withRouter(Card);
    
    

    カードリストに表示されているカードのコンポーネントは、ルーティングを個別に設定していないので、代わりにwithRouter設定になります。withRouterを設定すると、後で学ぶ履歴、match、locationを使用できます!


    カード設定で移動!

  • 上のコードを見るとcard-containerクリック時にhistoryで移動するのが見えます.
  • ここで("/mモンスター/ディテール/:1")これらのデータのid値を使って経路を設定できます.
  • でも流動性を変えるためにbackticを使う{this.props.id}!
  • this.props.idモンスターです.jsでフィルタリングされたデータを含むid.つまり、UIには検索で入力したデータのみを表示するカードが、IDをマッピングするたびに割り当てられる
  • ex)lを入力すると、3つのカードが出現すると、3つはそれぞれIDを送信し、カードリストにマッピングされたIDを1つずつカード素子に入れてhistorythis.props.id(計3回)
  • ここでちょっと待って~!!!!では、なぜ最初のレンダリング画面にすべてのカードトラフィックが表示されるのでしょうか。

    ----Monster.js------
     const {userInput, monsters} = this.state;
        const filteredData = monsters.filter((data) => {
          return (
            data.name.toLocaleLowerCase().includes(userInput.toLocaleLowerCase()) ||
            data.email.toLocaleLowerCase().includes(userInput.toLocaleLowerCase())
          );
        });
        return (
          <div className="Monsters">
            <h1>컴포넌트 재사용 연습!</h1>
            <SearchBox handleChange={this.handleChange} />
            <CardList monsters={filteredData} />
            {/* <SearchBox handleChange=정의한메소드 /> */}
            {/* <CardList monsters=몬스터리스트 /> */}
          </div>
        );
    

    ここで条件文を見ましょう!!最初のログイン時に入力されず、userInputには空の文字列「」が含まれています。include関数は空の文字列もtrueに戻ります!!実行済み、データが入力されていません。nameはすべてfilteringDataに割り当てられます!


    CardDetailのUIを表示!


    Cardを押して移動しますが、CardDetailはUIにデータを表示できません。これは、CardDetailがAPIデータ値を受信していないためです。そこでfetchを使ってデータを割り当てます!

    state = {
        data: {},
      };
      getData = () => {
        fetch(
          `https://-/users/${this.props.match.params.id}`
        )
          .then((res) => res.json())
          .then((res) =>
            this.setState({
              data: res,
            })
          );
      };
      componentDidMount() {
        this.getData();
      }
    

    これは、APIにロードされたデータに、さっきパスに設定したmonsters/detailを渡す簡単な方法です。props.match.paramsです!!このモンスターを通して


    http~~/users/monsters/detail.idはこのように入ることができます



    上からよく見えます。カードからプッシュ(/mモンスター/detale/${this.props.id});もしそうであれば、id値はアドレスパスに表示され、パスpropsが表示されます。すなわち、matchでid値を読み出すことで、id値に対応するデータをロードすることができる。


    ロードしたデータをstateに保存し、UIに表示するだけで済みます。

    
    ---CardDetail-----
    goToDetail = () => {
        this.props.history.push(`/monsters/detail/${this.props.id}`);
      };
    
    render() {
        const {id, name, email} = this.state.data;
    
        return (
          <div className="url-parameters">
            <div className="btn-wrapper">
              <button onClick={this.goToMonstersList}>Back to Monsters List</button>
            </div>
            <Card id={id} name={name} email={email} />
            <div className="btn-wrapper">
              <button onClick={this.goToPrevious}>Previous</button>
              <button onClick={this.goToNext}>Next</button>
            </div>
          </div>
        );
      }
    }
    

    上記のコードから,データはそれぞれカードにid,name,emailを割り当てる.ちなみに、ここでidをあげるのはCardDetailに現れたCardにあげるものです。先ほどのCardListのCard素子とは違います。


    CardDetailのBackBtn!

    goToMonstersList = () => {
        this.props.history.push('/');
      };
    

    簡単すぎる!!ボタンを押すと、初期画面の経路を再設定して終了!!


    CardDetailのpreBtnを表示!

      goToPrevious = () => {
        this.props.history.push(
          `/monsters/detail/${this.props.match.params.id - 1}`
        );
      };

    idの-1では、後ろのカードパスに直接移動できます。


    CardDetailのNextBtnを表示!

    
    goToNext = () => {
        this.props.history.push(
          `/monsters/detail/${+this.props.match.params.id + 1}`
        );
      };

    idに+1を加えると、前のカードパスに直接移動できます。ここで注意すべき点はstringなので、前に+に変更して加えます。


    このまま终わり?問題がある!



    nextは、prevボタンを押すたびにid値が変わりますが、データは変わりません。データが変更されると、データを再受信する必要があります。構成部品のジグルマウントが受信され、データの変更が開始された場合は、構成部品のジグル更新を使用します。URLは変わりますが、データは変わりません。パッチデータがないからです。ステータスが変わるたびに更新が実行されます。したがって、条件なしでsetStateを作成すると、構成部品の更新が続行され、パッチの受信が継続されるため、無限ロフトが実行されます。だから条件を設定しましょう!

     componentDidUpdate(prevProps, _) {
        if (prevProps.match.params.id !== this.props.match.params.id) {
          this.getData();
        }
      }
    

    デバイスジッタ更新prevProps、prevStateのパラメータを受け入れます。この元フロプスと昔の国を迎えに来ます。(ちなみに、離れるときは表示できます)。


    以前propsのmatch。params.idおよびコンポーネントアンインストールからパッチとして受信したprops。match.params.idが違うなら、パッチを持ってきてもいいですよ!


    prev、Nextキーをクリックしてparamsにします。idが変更されるので、以前とは違うしかない!!