Jig*_*val 5 javascript api reactjs react-router
我需要帮助才能停止在路线更改时再次进行相同的 API 调用。我试图在网络和 stackoverflow 上找到可用的解决方案,但我无法弄清楚修复此问题需要进行哪些更改。
我还尝试使用 sessionStorage 来存储一个标志,如果 API 调用被触发,则标志设置为 true,并且在路由器更改时,我检查标志是否为 true,然后不进行任何 API 调用。但随后它会将文章列表清空。
我有一个带路由的主要应用程序组件,其中包含两个组件:(请参阅下面给出的代码)
我面临的问题是,当我第一次点击时http://localhost:3001,它会重定向到http://localhost:3001/articles页面并正确呈现ArticleHome组件并获取文章列表。然后我单击“书签”链接,它会呈现http://localhost:3001/bookmarks路线和相关组件,并进行 API 调用来呈现书签列表。
但是,当我使用路由器返回“文章”页面时,http://localhost:3001/articles由于每次路由更改时组件都会重新渲染,它会再次触发 API 调用来获取文章。
谁能指导我如何在路由器更改和组件重新渲染时停止再次执行 API 调用?
如果数据已经加载,是否有更好的方法来处理同一组件的路由器更改上的 API 调用?
class App extends React.Component<any, any> {
constructor(props: any) {
super(props);
}
render() {
return (
<Router>
<React.Fragment>
<Switch>
<Route exact path="/" render={() => <Redirect to="/articles" />} />
<Route path="/articles" render={() => <ArticleHome type="articles" />} />
<Route path="/bookmarks" render={() => <BookmarkHome type="bookmarks" />} />
<Route path="*" component={NoMatch} />
</Switch>
</React.Fragment>
</Router>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
在 ArticleHome 组件中,我有一个用于获取文章列表的 API 调用,在 BookmarkHome 组件中,我有另一个用于获取书签列表的 API 调用。
ArticleHome组件:(BookmarkHome组件功能相同)
import React, { useReducer, useEffect, useState } from "react";
const ArticleHome = (props: any) => {
const [state, setState] = useState({
articles: [],
reRender: true
});
const [newState, dispatch] = useReducer(articleReducer, state);
useEffect(() => {
// componentWillUnmount
return () => {
console.log('unmounting 1...');
setState({
...state,
reRender: false
});
}
},[state.reRender]); // componentDidUpdate
const fetchAllrecords = () => {
fetch(url)
.then((data: any) => {
dispatch({ type: 'GET_ALL_RECORDS', data: data.docs })
return data.docs;
})
}
return (
<ul>
<li>Render article list here</li>
</ul>
)
}
// Reducer function
// ========================
function articleReducer(state: any, action: any) {
switch (action.type) {
case "GET_ALL_RECORDS":
return {
...state,
articles: action.data,
reRender: false
}
}
default:
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用路由器切换到上述任何组件时,它会再次执行 API 调用。
我已经[state.reRender]通过useEffect钩子告诉反应,仅当添加任何新项目或数据更新时才重新渲染组件。
在articleReducer功能中我正在设置reRender: false.
如果您需要这方面的更多信息,请告诉我。
谢谢,吉格内什·拉瓦尔
如果我是你,我会从路由组件之外的 api 获取数据,然后将其传递给路由。然后,您不必担心路由更改以及任何涉及操纵路由器默认行为的编程。您可以通过以下两种方法之一执行此操作。
首先, 您的 api 调用位于组件树的更高位置。因此,如果您在应用程序组件中执行 api 调用,然后将其传递给路线,您就不必担心路线的渲染。你的逻辑将在它之外。
其次, 如果您不想要混乱的应用程序组件,您可以创建一个上下文组件并在其中执行逻辑。然后只需将组件包装在您创建的上下文组件中即可。就像这样:
这是一个codesandbox沙盒
您的应用程序组件
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
import First from "./First";
import Second from "./Second";
import Context from "./Context";
import "./styles.css";
function App() {
return (
<BrowserRouter>
<div className="App">
<h1>Router Rerendering Fix</h1>
<ul>
<li>
<Link to="/">First Route</Link>
</li>
<li>
<Link to="/second">Second Route</Link>
</li>
</ul>
<Switch>
<Context>
<Route exact path="/" component={First} />
<Route path="/second" component={Second} />
</Context>
</Switch>
</div>
</BrowserRouter>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
您的文章组件
import React, { useContext } from "react";
import {ApiContext} from "./Context";
const First = () => {
const context = useContext(ApiContext);
return (
<div>
<div>First Route</div>
<ul>
{context.map((article, index) => (
<li key={index}>{article}</li>
))}
</ul>
</div>
);
};
export default First;
Run Code Online (Sandbox Code Playgroud)
您的上下文组件
import React, {useState, useEffect} from 'react';
export const ApiContext = React.createContext();
const Context = props => {
const [articles, setArticles] = useState([]);
useEffect(() => {
console.log('rendered');
setArticles(['Article One', 'Article Two', '...ect'])
}, []);
return (
<ApiContext.Provider value={articles}>
{props.children}
</ApiContext.Provider>
)
}
export default Context;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6208 次 |
| 最近记录: |