与GithubApi反应UseEffect问题获得贡献者

时间:2020-09-30 19:42:47

标签: javascript reactjs github react-hooks use-effect

感谢任何可以帮助我的人。我知道出现useEffect重新渲染的问题是很普遍的。 但是,在我的情况下,我将其设置为仅使用[]括号进行渲染一次,但它会始终重新渲染所有内容。

我在RepoItem.js组件中调用getRepoContributors()函数

我正在使用github api。我可以显示用户信息和用户回购。 但是,当我尝试为某个用户的回购寻求贡献者时,它会不断重新渲染。

无法弄清楚。 Github API由于多个请求而禁止我,整日迷失了方向,并且每次都需要等待大约一个小时才能再次尝试。

更新:第二天 仍然无法使其正常工作。现在尝试从Repos.js组件进行渲染。 但是我收到一条错误消息。 我在RepoItem.js中注释了我首先尝试的是哪些没有起作用的useeeffect。

“在呈现​​其他组件(GithubState)时无法更新组件(Repos)。”

请帮助!快疯了!这是我的更新文件。


GithubState.js(上下文提供程序)


import React, { useReducer } from "react";
import axios from "axios";
import GithubContext from "./githubContext";
import GithubReducer from "./githubReducer";
import { 
  SEARCH_USERS, SET_LOADING, CLEAR_USERS, GET_USER, GET_REPOS, 
  GET_CONTRIBUTORS, FILTER_REPOS, CLEAR_FILTER_REPOS 
} from "../types";

let githubClientId;
let githubClientSecret;
.....
.....

const GithubState = (props) => {
  const initialState = {
    users: [],
    user: {},
    repos: [],
    contributors: [],
    loading: false,
    filteredRepos: null,
    error: null,
  };

  const [state, dispatch] = useReducer(GithubReducer, initialState);

  //Search Users
  const searchUsers = async (text) => {
    setLoading();

    const res = await axios.get(
      `https://api.github.com/search/users?q=${text}&client_id=${githubClientId}&client_secret=${githubClientSecret}`
    );

    //res.data.items is response from Github API
    dispatch({
      type: SEARCH_USERS,
      payload: res.data.items,
    });
  };

  //Clear Users
  const clearUsers = () => {
    dispatch({ type: CLEAR_USERS });
  };

  //Set Loading
  const setLoading = () => {
    dispatch({ type: SET_LOADING });
  };

  //Get 1 User
  const getUser = async (username) => {
    setLoading();

    const res = await axios.get(
      `https://api.github.com/users/${username}?client_id=${githubClientId}&client_secret=${githubClientSecret}`
    );
    console.log(`getUser     res.data`, res.data);

    dispatch({ type: GET_USER, payload: res.data });
  };

  //Get Repos
  const getUserRepos = async (username) => {
    setLoading();

    const res = await axios.get(
      `https://api.github.com/users/${username}/repos?sort=created:asc&client_id=
    ${githubClientId}&client_secret=
    ${githubClientSecret}`
    );

    console.log(`getUserRepos res.data`, res.data);

    dispatch({
      type: GET_REPOS,
      payload: res.data,
    });
  };

  // Get Repo Contributors
  const getRepoContributors = async (full_name) => {
    setLoading();

    const res = await axios.get(
      `https://api.github.com/repos/${full_name}/contributors?client_id=${githubClientId}&client_secret=${githubClientSecret}`
    );

    console.log(`getRepoContributors`, res.data);
    dispatch({
      type: GET_CONTRIBUTORS,
      payload: res.data,
    });
  };

  //Filter Repos
  const filterRepos = (text) => {
    dispatch({ type: FILTER_REPOS, payload: text });
  };

  //Clear Filter
  const clearFilterRepos = (text) => {
    dispatch({ type: CLEAR_FILTER_REPOS });
  };

  return (
    <GithubContext.Provider
      value={{
        users: state.users,
        user: state.user,
        loading: state.loading,
        repos: state.repos,
        contributors: state.contributors,
        filteredRepos: state.filteredRepos,
        error: state.error,
        searchUsers,
        clearUsers,
        getUser,
        getUserRepos,
        getRepoContributors,
        filterRepos,
        clearFilterRepos,
      }}
    >
      {props.children}
    </GithubContext.Provider>
  );
};

export default GithubState;

App.js


import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import GithubState from "./contexts/github/GithubState";
import Home from "./components/pages/Home";
import User from "./components/users/User";

import "./App.css";

const App = () => {
  return (
    <GithubState>
        <Router>
          <div className="App">
              <Switch>
                <Route exact path="/" component={Home} />
                <Route exact path="/user/:login" component={User} />
              </Switch>
          </div>
        </Router>
    </GithubState>
  );
};

export default App;

User.js

import React, { useContext, useEffect } from "react";
import Spinner from "../layout/Spinner";
import Repos from "../repos/Repos";
import ReposFilter from "../repos/ReposFilter";
import { Link } from "react-router-dom";
import GithubContext from "../../contexts/github/githubContext";

const User = ({ match, iconGithub }) => {
  const githubContext = useContext(GithubContext);

  const { getUser, loading, user, repos, getUserRepos, getRepoContributors
  } = githubContext;

  useEffect(() => {
    getUser(match.params.login);
    getUserRepos(match.params.login);
  }, []);

  const { name, avatar_url, location, public_repos } = user;

  if (loading) return <Spinner />;

  return (
    <div className="userpage-container">
     .........
     <div className="card grid-2">
        <div>
         .............
          <h1>{name}</h1>
          <p>Location : {location}</p>

          <div className="card text-center">
           ............
            <div className="badge">
              Public Repos: : {public_repos}
            </div>
          </div>
        </div>
        ............ 
      </div>

      <ReposFilter />
      <Repos repos={repos} />
    </div>
  );
};

export default User;

Repos.js


import React, { useContext, useEffect, useState } from "react";
import RepoItem from "./RepoItem";
import RepoItemPacha from "./RepoItemPacha";
import GithubContext from "../../contexts/github/githubContext";
import Spinner from "../layout/Spinner";

const Repos = () => {
  const githubContext = useContext(GithubContext);

  const [repoContributors, setRepoContributors] = useState();

  const {
    repos,
    filteredRepos,
    loading,
    contributors,
    getRepoContributors,
  } = githubContext;

  if (repos !== null && repos.length === 0 && !loading) {
    return <h4>No repos to show</h4>;
  }

  return (
    <div className="text-center">
      <>
        {repos !== null && !loading ? (
          <div>
            {filteredRepos !== null
              ? filteredRepos.map((repo) => (
                  <div key={repo.id} className="item">
                    <RepoItemPacha repo={repo} />
                  </div>
                ))
              : repos.map((repo) => (
                  <div key={repo.id} className="item">
                    {repo && getRepoContributors(repo.contributors_url)}
                    {contributors.map((contr) => (
                      <div key={contr.id} className="item">
                        <h3>{contr.login}</h3>
                      </div>
                    ))}
                    <RepoItemPacha repo={repo} />
                  </div>
                ))}
          </div>
        ) : (
          <Spinner />
        )}
      </>
    </div>
  );
};

export default Repos;

RepoItem.js

import React, { useEffect, useContext, useState } from "react";
import GithubContext from "../../contexts/github/githubContext";

const RepoItemPacha = ({ repo }) => {
  const githubContext = useContext(GithubContext);

  const [repoContributors, setRepoContributors] = useState();

  const { getRepoContributors, contributors, repos } = githubContext;

  // useEffect(() => {
  //   if (repo) {
  //     getRepoContributors(repo.contributors_url);
  //     console.log(
  //       `getRepoContributors(repo.contributors_url)`,
  //       getRepoContributors(repo.contributors_url)
  //     );
  //   }
  // }, [repo]);

  // useEffect(() => {
  //   if (contributors) {
  //     setRepoContributors(contributors);
  //   }
  // }, []);

  // let theContributors = [getRepoContributors(repo.full_name)];

  return (
    <div className="card">
      <h3>
        <a href={repo.html_url} target="_blank" rel="noopener noreferrer">
          {repo.name}
        </a>
      </h3>
      <h4>{repo.collaborators_url}</h4>

      {/* {repoContributors &&
        repoContributors.map((contr) => (
          <div key={contr.id} className="item">
            <h3>{contr.login}</h3>
          </div>
        ))} */}

      {repo.description && (
        <p>
          <strong>Description: </strong>
          {repo.description}
        </p>
      )}
      <p></p>
      {repo.language && (
        <p>
          <strong>Language: </strong>
          {repo.language}
        </p>
      )}
    </div>
  );
};

export default RepoItemPacha;

0 个答案:

没有答案