![](/img/trans.png)
[英]React-native - this.setState only updating after second click
[英]React updating state only after second click
我正在嘗試構建一個 React 應用程序,但遇到了一個我似乎無法修復的錯誤。 我有一個上下文文件,其中包含一個days
變量和一個取決於天數的data
對象。 它看起來像這樣:
const DataContext = createContext({ days: 720, data: { timestamp: [], price: [], short_ma: [], long_ma: [], money: [], action: [] }, daysChangeHandler: (newDays) => { } })
export default DataContext
export const DataContextProvider = (props) => {
const daysChangeHandler = (newDays) => {
setDays(newDays, getNewData())
}
const getNewData = () => {
getData(days).then(response => setData(response))
console.log('NEW DATA')
}
const [days, setDays] = useState(720)
const [data, setData] = useState({ timestamp: [], price: [], short_ma: [], long_ma: [], money: [], action: [] })
return <DataContext.Provider
value={{ days: days, data: data, daysChangeHandler: daysChangeHandler }}>
{props.children}
</DataContext.Provider>
}
getData
觸發對數據庫的調用並取回數據,我對其進行了測試。
該應用程序包裝在dataContextProvider
。
當一個按鈕被點擊時,它看起來像這樣:
export default function NumberOfDays(props) {
const context = useContext(DataContext)
const predefinedDaysHandler = (days) => {
context.daysChangeHandler(days)
}
return <button className='submit-button' onClick={() => predefinedDaysHandler(0)}>Max</button>
}
最后,這應該顯示在一個渲染組件中,如下所示:
export default function DataChart(props) {
const context = useContext(DataContext)
console.log(context.data)
return //rendered data here, the updated data should be displayed but is only on the second time I click the submit button
}
問題是我必須在提交按鈕上單擊兩次才能獲取更新的數據值?
我曾嘗試在DataContextProvider
使用useEffect
:
useEffect(()=>{
getNewData(days)
}, [days])
但它什么都改變不了。
此外,當我第一次按下提交按鈕時, console.log('NEW DATA')
被觸發,但數據以某種方式沒有在應該在第二次單擊之前顯示我的數據的組件中更新。
確切地說,顯示的數據始終是上次更新之前的數據。 我該如何改變?
嘗試將daysChangeHandler
替換為:
const daysChangeHandler = (newDays) => {
setDays(newDays)
getNewData()
}
但它不會改變任何東西。
您的setState
方法無法正常工作,因為您向它傳遞了兩個參數。
在DataContextProvider
:
const DataContext = createContext({ days: 720, data: { timestamp: [], price: [], short_ma: [], long_ma: [], money: [], action: [] }, daysChangeHandler: (newDays) => { } })
export default DataContext
export const DataContextProvider = (props) => {
const daysChangeHandler = (newDays) => {
setDays(newDays)
getData(days).then(response => setData(response))
}
const [days, setDays] = useState(720)
const [data, setData] = useState({ timestamp: [], price: [], short_ma: [], long_ma: [], money: [], action: [] })
return <DataContext.Provider
value={{ days: days, data: data, daysChangeHandler: daysChangeHandler }}>
{props.children}
</DataContext.Provider>
}
如果您想在setDays
使用回調函數來獲取具有先前實現的新數據:
const daysChangeHandler = (newDays) => {
setDays(newDays, () => getNewData())
}
const getNewData = () => {
getData(days).then(response => setData(response))
console.log('NEW DATA')
}
此外,您可以以更短的方式將值對象傳遞給DataContext.Provider
,因為key
和value
是相等的:
return (
<DataContext.Provider
value={{ days, data, daysChangeHandler }}>
{props.children}
</DataContext.Provider>
)
解決方案是調用useEffect
並將days
設置為上下文內的依賴項:
useEffect(() => {
getData(days).then(response => setData(response))
}, [days]);
我制作了一個特定於您的用例的模型
你可以去CodeSandbox和我的Demo進行交互。 但代碼就在下面
context.tsx 文件
import { createContext, useState } from "react";
const mockUp = {
days: 720,
data: {
timestamp: [],
price: [],
short_ma: [],
long_ma: [],
money: [],
action: []
},
daysChangeHandler: (newDays) => {}
};
const DataContext = createContext(mockUp);
export default DataContext;
export const DataContextProvider = (props) => {
const [days, setDays] = useState(720);
const [data, setData] = useState(mockUp);
const daysChangeHandler = (newDays) => {
getNewData();
setDays(newDays);
};
const getNewData = () => {
// getData(days).then(response => setData(response))
// getData(days) mock up
Promise.resolve(mockUp).then((res) =>
setData(() => ({ ...res, days: 370 }))
);
console.log("NEW DATA");
};
return (
<DataContext.Provider
value={{ days: days, data: data, daysChangeHandler: daysChangeHandler }}
>
{props.children}
</DataContext.Provider>
);
};
數據圖表.tsx
import { useContext, useEffect } from "react";
import DataContext from "./context";
export default function DataChart(props) {
const { data } = useContext(DataContext);
useEffect(() => {
console.log("data chart", data);
}, [data]);
return null; //rendered data here, the updated data should be displayed but is only on the second time I click the submit button
}
天數.tsx
import { useContext } from "react";
import DataContext from "./context";
export default function NumberOfDays(props) {
const context = useContext(DataContext);
const predefinedDaysHandler = (days) => {
context.daysChangeHandler(days);
};
return (
<button className="submit-button" onClick={() => predefinedDaysHandler(0)}>
Max
</button>
);
}
app.tsx 文件
import { DataContextProvider } from "./context";
import DataChart from "./DataChart";
import NumberOfDays from "./NumberOfDays";
export default function App() {
return (
<DataContextProvider>
<DataChart />
<NumberOfDays />
</DataContextProvider>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.