2 回答

TA貢獻1856條經驗 獲得超11個贊
好的,我運行了你的代碼并找出了問題所在。 正在更改,但它不會觸發 的重新渲染 。因此,您的 in 只運行一次(在初始渲染時)。要觸發重新渲染,您需要使用以下命令創建和更新:dataChartWrapperuseEffectChartWrapperdatauseState
let [data, setData] = useState([])
function newVal() {
let obj = null;
let val = Math.floor(Math.random() * 10);
let timeNow = Date.now();
obj = {'time': timeNow, 'value': val};
const newData = [...data]
newData.push(obj)
setData(newData)
}
但是,這還不夠。由于您的函數定義了一次,因此其調用上下文中的值將始終是 的初始值(即空數組)。您可以通過在函數中執行此操作來查看這一點。要解決此問題,您也可以添加為依賴項:setIntervaldatadataconsole.log(data)newValdatauseEffect
useEffect(() => {
setInterval(newVal, 1000);
}, [data]);
但是,每次數據更改時,您都會創建一個新的;你最終會同時運行其中的許多。您可以通過從中返回一個函數來清理setInterval:setIntervaluseEffectclearInterval
useEffect(() => {
const interval = setInterval(newVal, 1000);
return () => clearInterval(interval)
}, [data]);
但是在這一點上,你不妨改用:setTimeout
useEffect(() => {
const timeout = setTimeout(newVal, 1000);
return () => clearTimeout(timeout)
}, [data]);
這將導致每次更改時都會創建一個新的,因此它將像您的 .setTimeoutdatasetInterval
無論如何,你的代碼看起來像這樣:
const ChartWrapper = (props) => {
useEffect(
() => {
console.log('function called');
}, [props.data]
);
return <p>asdf</p>
}
const App = () => {
let [data, setData] = useState([])
function newVal() {
let obj = null;
let val = Math.floor(Math.random() * 10);
let timeNow = Date.now();
obj = {'time': timeNow, 'value': val};
const newData = [...data]
newData.push(obj)
setData(newData)
}
useEffect(() => {
const timeout = setTimeout(newVal, 1000);
return () => clearTimeout(timeout)
}, [data]);
return (
<ChartWrapper data={data} />
)
}
還有一個運行的例子:https://jsfiddle.net/kjypx0m7/3/
需要注意的是,這與 ChartWrapper 的依賴關系一樣運行良好。這是因為當被調用時,它總是被傳遞一個新的數組。因此,當 ChartWrapper 重新渲染時,實際上是不同的。useEffect[props.data]setDataprops.data

TA貢獻1850條經驗 獲得超11個贊
鉤子依賴關系中的對象通過引用進行比較。由于數組也是對象,因此當您說對數組的引用不會更改時,因此不會觸發鉤子。data.push
另一方面,基元值按值進行比較。由于 是 基元類型 (),因此出于您的目的,將依賴項放在上可以解決問題。data.length
number
data.length
但是,如果不修改數組的長度,只修改數組中的值,則觸發引用差異的最簡單方法(如第一段中所述)是將此數組包裝在鉤子中。setState
下面是一個工作示例:https://codesandbox.io/s/xenodochial-murdock-qlto0。將子組件中的依賴項從 更改為 沒有區別。[data.length]
[data]
添加回答
舉報