问题描述
我的代码发生了一些奇怪的事情。当我在触发 onpopstate 事件时调用我的回调时,我的变量数据(useState)随机为空。 我有 2 个组件和 1 个像这样使用的钩子:
const Parent = props => {
const {downloadData} = useData();
const [data,setData] = useState([]);
const [filteredData,setFilteredData] = useState();
const loadData = async () => setData(await downloadData());
useEffect(() => {
loadData();
},[]);
return <FilterPage data={data} onDataChange={data => setFilteredData(data)} />
}
const FilterPage = ({data,onDataChange} => {
const {saveHistoryData} = useHistoryState('filter',null,() => {
updatefilters();
});
const filter = (filterData,saveHistory = true) => {
let r = data; // data is randomly empty here
...
if(saveHistory)saveHistoryData(filterData);
onDataChange(r);
}
});
// my hook
const useHistoryState = (name,_data,callback) => {
const getHistoryData = () => {
const params = new URLSearchParams(window.location.search);
try{
return JSON.parse(params.get(name));
}catch(err){
return null;
}
}
const saveHistoryData = (data) => {
const params = new URLSearchParams(window.location.search);
params.set(name,JSON.stringify(data || _data));
window.history.pushState(null,'',window.location.pathname + '?' + params.toString());
}
const removeHistoryData = () => {
const params = new URLSearchParams(window.location.search);
params.delete(name);
window.history.pushState(null,window.location.pathname + '?' + params.toString());
}
const watchCallback = () => {
callback(getHistoryData());
};
useEffect(() => {
let d = getHistoryData();
if(d)watchCallback();
window.addEventListener('popstate',watchCallback);
return () => window.removeEventListener('popstate',watchCallback);
},[]);
return {getHistoryData,saveHistoryData,removeHistoryData};
}
任何建议请
编辑 对不起不是完整的代码,只是一个草稿。我使用异步功能下载数据。数据加载正常,但只有当我们从钩子调用回调时才为空。
解决方法
您需要使用 setData
来填充 data
首先,您不会在任何地方调用 setData()
。
您使用的是 data
而不是 setData
,您使用的是 setFilteredData
而不是 filteredData
。
此外,updateFilters()
中似乎不存在 FilterPage
。
您将 onDataChange
传递给 <Filterpage>
,但您没有使用该属性,只有 ({data})
解释了为什么它是空的。您可能想要更新 FilterPage 签名:const FilterPage = ({data,onDataChange}) => {}
并使用 onDataChange