[英]How to re-render and run useEffect when router change (React js)
我有一個ChartPage
函數,它在三個不同的路由器內被調用了三次,在該ChartPage
函數中,我使用的是“useEffect”,它根據所選路由更新一些變量。 但由於某種原因,它只觸發一次,當我要去使用相同ChartPage
功能的不同路線時,“useEffect”不會再次觸發,即使路線正在改變,數據仍然與第一條路線相同被觸發了。
有人可以幫助解決這個問題嗎,我試圖解決這個問題幾個小時
基本上我想在單擊其中一個按鈕時觸發“useEffect”
應用程序.js :
import React from "react";
import Navbar from "./components/Navbar";
import "./App.css";
import Home from "./components/pages/Home";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import ShowStocks from "./components/pages/ShowStocks";
import ChartPage from "./components/pages/ChartPage";
function App() {
return (
<>
<Router>
<Navbar />
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/show-stocks" element={<ShowStocks />} />
<Route
path="show-stocks/bitcoin"
element={<ChartPage type={"BTC"} />}
/>
<Route
path="show-stocks/ethereum"
element={<ChartPage type={"ETH"} />}
/>
<Route
path="show-stocks/cardano"
element={<ChartPage type={"ADA"} />}
/>
</Routes>
</Router>
</>
);
}
export default App;
如您所見,我在三種不同的路線中使用ChartPage
,但使用的數據不同
ChartPage.js :
import React, { Component, useState, useEffect } from "react";
import "../../App.css";
import Chart from "../Chart";
import { Button } from "../Button.js";
import "./ChartPage.css";
import axios from "axios";
function getCoin(type) {
console.log("requesting");
var path = `/show-stocks/${type}`;
return axios.get(path).then((response) => {
return response.data;
});
}
export default function ChartPage({ type }) {
const [values, setValues] = useState(null);
// type is changing correctly and the function did get called with a different type
// but useEffect doesn't run on the second time
// so getCoin does not get triggerd and the data stays the same
useEffect(() => {
getCoin(type)
.then((response) => {
setValues(response);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
<>
<div className="chart-page-container">
<h1>{type} Price Market Value</h1>
<div className="chart-container">
{null !== values ? (
<Chart data={[values, type]} />
) : (
<p>Loading...</p>
)}
</div>
<div className="chart-page-btns">
<Button
link="/show-stocks/bitcoin"
className="btns"
buttonStyle="btn--outline2"
buttonSize="btn--large2"
>
Bitcoin
</Button>
<Button
link="/show-stocks/ethereum"
className="btns"
buttonStyle="btn--outline2"
buttonSize="btn--large2"
>
Ethereum
</Button>
<Button
link="/show-stocks/cardano"
className="btns"
buttonStyle="btn--outline2"
buttonSize="btn--large2"
>
Cardano
</Button>
</div>
</div>
</>
);
}
如您所見,更改路由和類型的按鈕會根據路由發送的參數進行更新,但 useEffect 不會再次調用。
將type
添加到useEffect
的依賴項數組中:
useEffect(() => {
getCoin(type)
.then((response) => {
setValues(response);
})
.catch((error) => {
console.log(error);
});
}, [type]); // <= HERE
請記住,此代碼存在一些問題,因為如果發生這種情況,您最終可能會看到與 URL 中的類型不匹配的類型的數據:
/type-a
並getCoin('type-a')
。/type-b
並getCoin('type-b')
。type-b
完成加載,所以它的then
回調被執行。type-a
完成加載,所以它的then
回調被執行。/type-b
中,但可以看到來自type-a
數據。正確的方法是這樣的:
useEffect(() => {
let shouldUpdate = true;
getCoin(type)
.then((response) => {
if (shouldUpdate) setValues(response);
})
.catch((error) => {
console.log(error);
});
// This cleanup function will be called if the `useEffect`'s
// dependencies change, so if you run it twice in a row for
// different types, when the result of the first one arrives,
// it will be discarded:
return () => {
shouldUpdate = false;
};
}, [type]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.