gpt4 book ai didi

javascript - 使用 React Router 4 响应持久状态

转载 作者:行者123 更新时间:2023-12-03 07:09:08 25 4
gpt4 key购买 nike

我的主页正在从 API 获取数据,将其放入组件的状态并根据此状态渲染元素。当我导航到一个子页面然后我想再次进入主页时,数据会被再次获取,这会导致不必要的负载。如何防止这种情况?如何确保当我单击主页链接或后退按钮时数据会立即加载?

import React, {Component} from 'react';
import axios from 'axios';
import _ from 'lodash';
import { Link } from 'react-router-dom';

import ContributorsTable from './ContributorsTable';
import LoadingScreen from './LoadingScreen';

export const API_KEY = 'api-key'
const org = `https://api.github.com/orgs/angular?${API_KEY}`;
const unorderedContributors = [];
let contributorsList = [];
const contributorPromises = [];
const contributorPropertiesPromises = [];

class GitHubLists extends Component {
constructor(props) {
super(props);

this.state = {
repos: [],
contributors: [],
isLoaded: false
};
}
componentDidMount() {
axios.get(org)
.then(res => {
let numberRepos = res.data.public_repos;
let pages = Math.ceil(numberRepos/100);
let tmpRepos = [...this.state.repos];
for(let page = 1; page <= pages; page++) {
axios.get(`https://api.github.com/orgs/angular/repos?page=${page}&per_page=100&${API_KEY}`)
.then(res => {
for(let i = 0; i < res.data.length; i++) {
tmpRepos.push(res.data[i]);
}
this.setState({repos: tmpRepos});
})
.then(() => {
this.state.repos.map(repo =>
contributorPromises.push(axios.get(`${repo.contributors_url}?per_page=100&${API_KEY}`)
.then(res => {
if(!res.headers.link) {
unorderedContributors.push(res.data);
}

else {
for(let page = 1; page <= 5; page++) {//5 pages because of github limitation - can be done by recursion checking if res.headers.link.includes('rel="next"')
contributorPromises.push(
axios.get(`${repo.contributors_url}?page=${page}&per_page=100&${API_KEY}`)
.then(res => unorderedContributors.push(res.data))
)
}
}
}))
);

Promise.all(contributorPromises).then(() => {

contributorsList = _.chain(unorderedContributors)
.flattenDeep()
.groupBy('id')
.map((group, id) => ({
id: parseInt(id, 10),
login: _.first(group).login,
contributions: _.sumBy(group, 'contributions'),
contributorFollowers: 0,
followers_url: _.first(group).followers_url,
contributorRepositories: 0,
repos_url: _.first(group).repos_url,
contributorGists: 0,
gists_url: _.first(group).gists_url,
avatar: _.first(group).avatar_url,
url: _.first(group).html_url
}))
.orderBy(['contributions'],['desc'])
.filter((item) => !isNaN(item.id))
.value();

this.setState({contributors: contributorsList})
})
.then(() => {
let tmpContributors = [...this.state.contributors];
tmpContributors.map(contributor => contributor.gists_url = (contributor.gists_url).slice(0, -10));
tmpContributors.map(contributor => {
return contributor.link =
<div>
<Link
to={{
pathname: `contributors/${contributor.login}`,
state: {
login: contributor.login,
id: contributor.id,
repos_url: contributor.repos_url,
avatar: contributor.avatar
}
}}
>
See profile
</Link>
</div>
});
const getContributorProperties = (propertyUrl, contributorProperty) => {
for (let i = 0; i < 10; i++) {
contributorPropertiesPromises.push(axios.get(`${tmpContributors[i][propertyUrl]}?per_page=100&${API_KEY}`)
.then(res => {
if(res.data.length > 100) {
tmpContributors[i][contributorProperty] = res.data.length;
}
else {
for(let page = 1; page <= 5; page++) {
axios.get(`${tmpContributors[i][propertyUrl]}?page=${page}&per_page=100&${API_KEY}`)
tmpContributors[i][contributorProperty] += res.data.length;
}
}
})
)
}
}
getContributorProperties('followers_url', 'contributorFollowers');
getContributorProperties('repos_url', 'contributorRepositories');
getContributorProperties('gists_url', 'contributorGists');
Promise.all(contributorPropertiesPromises)
.then(() => this.setState({contributors: tmpContributors, isLoaded: true}))

})
})
}
})
}
render() {
if(this.state.isLoaded) {
return <ContributorsTable data={this.state.contributors}/>;
}
else {
return <LoadingScreen />
}
}
}

export default GitHubLists;

最佳答案

与其将您的状态保持在路由级别,不如将其保持在应用程序级别(或在 url 更改/子安装 + 卸载时持续存在的某个地方,如 redux 存储)。

class App {
state = { data: null }
fetchData() {
callApi().then(data => this.setState({ data }))
}
render() {
return (
<Router>
<div>
<Route
path="/page"
component={props =>
<Page data={this.state.data} fetchData={this.fetchData} />
}
/>
</div>
</Router>
)
}
}

class Page {
componentDidMount() {
if (!this.props.data) this.props.fetchData()
}
render() { ... }
}

React 文档有一个关于“提升状态”的地方。使用 React Router 时同样的原则适用:https://facebook.github.io/react/docs/lifting-state-up.html

关于javascript - 使用 React Router 4 响应持久状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45805436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com