如何修复我的 React 上下文以呈现 useEffect 并重新加载 table 数据
How to fix my React Context to render useEffect and reload table data
我有一个输入表单,可以选择要在我的 table 中呈现的数据。数据仅在强制页面重新加载后出现。我希望在我的输入中每次提交后使用用户输入的预期数据重新呈现数据。
为此我有:
- 一个名为
SymbolInput()
的输入函数,它将用户请求的数据发送到我的数据库。
- 一个 table 函数,
PriceUpdate()
通过 useEffect 从我的数据库加载数据。
createContext
作为传输器通过 useEffect 依赖数组重新加载 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 项目。
我有一个输入表单,可以选择要在我的 table 中呈现的数据。数据仅在强制页面重新加载后出现。我希望在我的输入中每次提交后使用用户输入的预期数据重新呈现数据。
为此我有:
- 一个名为
SymbolInput()
的输入函数,它将用户请求的数据发送到我的数据库。 - 一个 table 函数,
PriceUpdate()
通过 useEffect 从我的数据库加载数据。 createContext
作为传输器通过 useEffect 依赖数组重新加载 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
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 项目。