簡體   English   中英

狀態不會第一次改變

[英]The state does not change the first time

當我點擊“下一步”按鈕時,state.page 第二次更新。 如果我向前滾動幾次並想要顯示新的存儲庫,它也只會從第二次按下時輸出。 幫助修復它。 CodeSandBox 項目: https ://codesandbox.io/s/lab9rest-api-eupg0

布局.js

import React from "react";
import axios from "axios";
import ReposList from "./ReposList";

export default class Layout extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      page: 1,
      pages: 100,
      per_page: 10
    };
  }

  searchNew() {
    this.setState(() => {
      return { page: 1 };
    });

    this.search();
  }

  search() {
    let text = document.getElementById("search-text").value;

    if (text !== "") {
      let sort = document.getElementById("sort-items").value;
      let sortValue = sort.split("-")[1];
      let pagination =
        "&page=" + this.state.page + "&per_page=" + this.state.per_page;
      let url =
        "https://api.github.com/search/repositories?q=" + text + pagination;

      if (sort === "best-matches") url += "&order=desc";

      if (sort === "most-stars") url += "&sort=" + sortValue + "&order=desc";

      if (sort === "fewest-stars") url += "&sort=" + sortValue + "&order=asc";

      if (sort === "most-followers")
        url += "&sort=" + sortValue + "&order=desc";

      if (sort === "fewest-followers")
        url += "&sort=" + sortValue + "&order=asc";

      if (sort === "most-forks") url += "&sort=" + sortValue + "&order=desc";

      if (sort === "fewest-forks") url += "&sort=" + sortValue + "&order=asc";
      console.log(this.state.page);
      axios(url)
        .then(response => {
          if (response.data.items.length !== 0) {
            this.setState(() => {
              return {
                data: response.data.items
              };
            });
          } else alert("Репозиториев не найдено.");
        })
        .catch(error => {
          alert("Не удалось обработать инструкции '" + text + "'.");
        });
    }
  }

  nextPage() {
    if (this.state.page !== this.state.pages)
      this.setState(state => {
        return { page: state.page + 1 };
      });
    else
      this.setState(() => {
        return { page: 1 };
      });

    this.search();
  }

  changePerPage() {
    let per_page = document.getElementById("per_page").value;
    let pages = Math.floor(1000 / per_page);
    console.log(pages);
    this.setState(() => {
      return { per_page: per_page, pages: pages };
    });
  }

  changeCurrentPage(page) {
    this.setState(() => {
      return { page: page };
    });
  }

  render() {
    return (
      <div>
        <h3>Repository search</h3>
        <div id="search">
          <select id="sort-items" onChange={() => this.changeCurrentPage(1)}>
            <option value="best-match">Best match</option>
            <option value="most-stars">Most stars</option>
            <option value="fewest-stars">Fewest stars</option>
            <option value="most-forks">Most forks</option>
            <option value="fewest-forks">Fewest forks</option>
            <option value="most-followers">Most followers</option>
            <option value="fewest-followers">Fewest followers</option>
          </select>
          <input type="text" id="search-text" />
          <button onClick={() => this.searchNew()}>Search</button>
        </div>
        <div id="settings">
          <p>output amount</p>
          <input
            type="number"
            min="1"
            defaultValue="10"
            max="100"
            id="per_page"
            onChange={() => this.changePerPage()}
          />
        </div>
        <ReposList data={this.state.data} />
        <div id="pagination">
          {this.state.page}
          <button onClick={() => this.nextPage()}>Next</button>
        </div>
      </div>
    );
  }
}

RepoList.js

import React from "react";
import Repo from "./Repo";

export default class ReposList extends React.Component {
  render() {
    return (
      <div id="repos">
        {this.props.data.map((repo, index) => {
          return (
            <Repo
              key={index}
              avatar={repo.owner.avatar_url}
              login={repo.owner.login}
              url={repo.url}
              name={repo.name}
            />
          );
        })}
      </div>
    );
  }
}

回購協議

import React from "react";

export default function Repo(props) {
  return (
    <div className="repo">
      <img src={props.avatar} alt="avatar" />
      <p className="login">{props.login}</p>
      <a className="url" href={props.url}>
        {props.name}
      </a>
    </div>
  );
}

實際上,您的狀態會在第一次點擊時更新 - 但稍后。

setState不是同步的行動,改變this.state的權利,但它盡快做它有時間重新呈現

因此,當您在this.setState之后直接調用this.search()this.state尚未更新,您將繼續使用舊值。

setState 實際上接受一個回調作為第二個參數,所以為了確保this.search只在狀態持續this.search被調用,你可以這樣做

searchNew() {
    this.setState(() => {
      return { page: 1 };
    },
    () => this.search()
  );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM