如果我的应用从/profile/1
转到/company/1
,然后又回到/profile/1
,则该页面不应再次获取数据。
路由器配置:
<Switch>
<Route path="/profile/:id" component={Profile}/>
<Route path="/company/:id" component={Company}/>
</Switch>
个人资料组件
class Profile extends React.Component {
componentDidMount() {
this.fetchUserProfile(this.props.match.params.id);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.match.params.id !== this.props.match.params.id) {
console.log("fetching profile again");
this.fetchUserProfile(this.props.match.params.id);
}
}
render(){
return <Link to={"/company/1"}>company</Link>
}
}
如何阻止Profile
重新获取api? componentDidUpdate
在这里没有帮助。
答案 0 :(得分:2)
您可以将数据缓存在sessionStorage
或localStorage
之类的文件中,也可以使用 redux 。
您可以在此处了解有关sessionStorage
的更多信息:MDN Web Docs on sessionStorage
然后在您的componentDidMount
中,您可以检查数据是否已经在缓存中退出,并且只有在数据没有提取时才可以获取。
以下是使用componentDidMount
时sessionStorage
的外观示例:
componentDidMount() {
let data = sessionStorage.getItem('profileData'); //Get the data from sessionStorage
if(data) {
this.setState({profile: data}) // Used cached data
}
else {
this.fetchUserProfile(this.props.match.params.id); // Fetch data
}
}
答案 1 :(得分:1)
扩展以前的答案,这是您可以使用的完全不同的方法。加载数据后,使用React Context API存储数据。
https://reactjs.org/docs/context.html
使用上下文,您可以轻松地存储数据,并在重新呈现组件时检查数据是否已经加载。这是一个可快速运行的示例,您可以看到_fetch仅在第一个渲染器上触发。
const Context = React.createContext({});
// Home
const Home = () => {
return <div>Homepage</div>;
};
// Profile
const Profile = () => {
const context = React.useContext(Context);
const _fetch = () => {
console.log("fetching... it only fetches it once");
return new Promise(resolve => resolve({ message: "ok!" }));
};
React.useEffect(() => {
if (!context.cache) {
_fetch().then(data => context.setCache(data));
}
}, [context]);
return context.cache ? <div>{context.cache.message}</div> : <div>...</div>;
};
// App
function App() {
const [cache, setCache] = React.useState(null);
return (
<Context.Provider value={{ cache, setCache }}>
<div className="App">
<ReactRouterDOM.MemoryRouter>
<ul>
<ReactRouterDOM.Link to="/">
<li>Home</li>
</ReactRouterDOM.Link>
<ReactRouterDOM.Link to="/profile">
<li>Profile</li>
</ReactRouterDOM.Link>
</ul>
<ReactRouterDOM.Switch>
<ReactRouterDOM.Route exact={true} path="/" component={Home} />
<ReactRouterDOM.Route exact={true} path="/profile" component={Profile} />
</ReactRouterDOM.Switch>
</ReactRouterDOM.MemoryRouter>
</div>
</Context.Provider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/5.1.2/react-router-dom.min.js" integrity="sha256-Ga/RV3YJI+cd1/ML8yitEoluFHUJZ7HTH90az8fOFZU=" crossorigin="anonymous"></script>
<div id="root"></div>