簡體   English   中英

僅在第二次單擊后才反應更新狀態

[英]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 ,因為keyvalue是相等的:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM