如何修复我的 React 上下文以呈现 useEffect 并重新加载 table 数据

How to fix my React Context to render useEffect and reload table data

我有一个输入表单,可以选择要在我的 table 中呈现的数据。数据仅在强制页面重新加载后出现。我希望在我的输入中每次提交后使用用户输入的预期数据重新呈现数据。

为此我有:

问题: 我没有收到任何错误,我知道我做错了什么,我无法为我的特定用例考虑上下文 API。因此,我将不胜感激一些澄清,让我自己理解 useContext 及其提供者。

这是我的代码:

下面我启动我的createContext:

import { createContext } from 'react';

export const TableRefreshContext = createContext();
export default TableRefreshContext;

然后将上下文导入我的文件,其中包含我的输入表单。在这里,我使用状态作为 trigger/key 来重新渲染我的 table。如果数据发送到我的数据库,则状态键递增 1,希望在我的 table 函数中触发 useEffect 依赖数组。

import TableRefreshContext from '../../../context/TableRefresh';

export default function SymbolInput()
{
  const { control, handleSubmit } = useForm();
  const [refreshKey, SetRefreshKey] = useState([0])

  const onSubmit = (data, e) =>
  {  

    axiosInstance
      .patch(URL, {
        stock_list: data.stock_list.map(list=>list.symbol),
      })
      .then((res) =>
      {
        SetRefreshKey(refreshKey + 1);
      });
  };

  return (
    <TableRefreshContext.Provider value={refreshKey}>
            <form> 
            </form> 
    </TableRefreshContext.Provider>
    );
}

这是我提到的 table 函数,其中我有一个 useEffect 从我的数据库中提取数据,以及它的依赖数组。

export function PriceUpdate()
{
    const [data, setData] = useState([]);
    const reloadTable = useContext(TableRefreshContext)
    useEffect(() =>
    {
        const fetchData = async () =>
        {
            const response = await axiosInstance.get(URL)
            const result = response.data;
            setData(result);
        };

        fetchData();
    }, [reloadTable]);

    return (
        <>
            <div>
            <TableRefreshContext.Provider value={reloadTable}>
                <PriceUpdates data={data[0]} />
                <PriceRanges data={data[0]} />
                <ReturnRates data={data[1]} />
                <QuickFacts data={data[2]} />
                <Recommendations data={data[4]} />
                <AdvancedStats data={data[3]} />
            </TableRefreshContext.Provider>

如何 link 将我的输入和 table 功能结合起来,让我的页面呈现新数据而无需重新加载整个页面?

编辑: 这是我如何使用 PriceUpdate 组件,它是我的布局组件的子组件之一:


    const reloadTable = useContext(TableRefreshContext)

    return (
            <TableRefreshContext.Provider value={reloadTable}>
                <PriceUpdate />
            </TableRefreshContext.Provider>
    );
}

即兴发挥,我发现您的代码有一点不对,即在 refreshKey 的 useState 中,您初始化了一个包含 0 的数组,即 [0] 而不是数字 0。所以您的 setRefreshKey 不是按预期工作。这应该可以解决您的问题。

另一个建议,从 useEffect 中删除您的 fetchData 函数。它在每个渲染器上再次定义函数。而是使用 useCallback:

在 useEffect 之外定义它
const fetchData = useCallback(async () => {
  const response = await axiosInstance.get(URL)
  const result = response.data;
  setData(result);
}, [])

它会进入一个循环,因为你已经在 useEffect() 中设置了状态。在 useEffect() 中使用 setState 是可以的,你只需要注意已经描述的不要创建循环你可以检查控制台错误。

来自对 useContext

的反应 docs

Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest <MyContext.Provider> above the calling component in the tree

...其中,MyContext 类似于您的 TableRefreshContext。因此,您需要确保 PriceUpdate 在层次结构的更高位置有 TableRefreshContext.Provider。您在评论中提到它没有嵌套。我认为它不可能在没有嵌套的情况下接收更改的上下文值。

从您提供的当前代码来看,我认为它没有任何问题,除了 refreshKey 应该是一个数字而不是一个数组。我创建了一个 CodeSandbox project 几乎与您的应用程序相同,并没有发现它有任何问题(请注意,不推荐使用这种使用 Context 的方式,因为它应该在更高的层次结构中,如前一个 post).

如果您的代码仍然无法正常工作,请尝试创建一个可以重现您的问题的 CodeSandbox 项目。