我有两个正在使用的组件。在第一个组件中,我制作了一个自定义useEffect钩子,该钩子从服务器中检索数据。请参见下面的代码:
一个代码段
import {useState, useCallback} from 'react';
import {stageQuizApi} from '../api/quiz';
import {QuestionService} from "../services/IdDbServices/question_service";
const usePostData = ({url, payload, config}) => {
const [res, setRes] = useState({data: null, error: null, isLoading: false});
const callAPI = useCallback(() => {
setRes(prevState => ({...prevState, isLoading: true}));
stageQuizApi.patch(url, payload, config).then( res => {
setRes({data: res.data, isLoading: false, error: null});
const questionInDb = {};
const {NoTimePerQuestion,anwser, question, playerDetails, option} = res.data.data;
const {playerid,anwserRatio, name} = playerDetails
questionInDb.timePerQuestion = NoTimePerQuestion;
questionInDb.anwserRatio = anwserRatio;
questionInDb.options = option;
questionInDb.answer = anwser;
questionInDb.playerId = playerid;
questionInDb.name = name;
questionInDb.question = question;
const Service = new QuestionService();
Service.addStudent(questionInDb).
then(response=>console.log(response))
.catch(err=>console.log(err));
}).catch((error) => {
console.log(error)
if (error.response) {
const errorJson = error.response.data
setRes({data: null, isLoading: false, error: errorJson.message});
} else if (error.request) {
setRes({data: null, isLoading: false, eror: error.request});
} else {
setRes({data: null, isLoading: false, error: error.message});
}
})
}, [url, config, payload])
return [res, callAPI];
}
export default usePostData;
以上模块具有双重目的。它首先向我的端点发出axios请求,其次向浏览器IndexDb插入数据库(类似于localstorage,但使用sql方法)(例如使用从第一个请求获得的响应将数据插入数据库。因此通常我有一个 .then
外部的诺言部分。
第二个代码段
const questionInDb = {};
const {NoTimePerQuestion,anwser, question, playerDetails, option} = res.data.data;
const {playerid,anwserRatio, name} = playerDetails
questionInDb.timePerQuestion = NoTimePerQuestion;
questionInDb.anwserRatio = anwserRatio;
questionInDb.options = option;
questionInDb.answer = anwser;
questionInDb.playerId = playerid;
questionInDb.name = name;
questionInDb.question = question;
const Service = new QuestionService();
Service.addStudent(questionInDb).
then(response=>console.log(response))
.catch(err=>console.log(err));
这是问题所在,我试图保持状态,因为我希望该模块的结果在另一条路线中共享,并且我不想再次击中服务器,因此我将结果插入了indexDb浏览器存储中。这是执行上述模块的代码:
代码段三
const displaySingleQuestion = ()=>{
OnUserGetQuestion();
history.push('/player/question');
}
上述方法是从我的第一条路线 /question
中调用的,并且当时,可以将用户重定向到 /player/question
displaySingleQuestion
被调用。
然后在新路径 /player/question
上,我想从IndexDb中获取数据并使用下面的useEffect代码更新该组件的状态:
第四代码段
useEffect(()=>{
const getAllUserFromIndexDb = async()=>{
try{
const result = await new Promise((resolve, reject) => {
service.getStudents().then(res=>resolve(res)).catch(err=>reject(err))
});
console.log('it did not get to the point i was expecting',result)
if(result[0]){
console.log('it got to the point i was expecting')
const singleQuestion = result[0];
const questionPage = playerQuestionToDisplay;
questionPage.name = singleQuestion.name;
questionPage.anwserRatio = singleQuestion.anwserRatio;
questionPage.answer = singleQuestion.answer;
questionPage.options = singleQuestion.options;
questionPage.playerId = singleQuestion.playerId;
questionPage.question = singleQuestion.question;
questionPage.timePerQuestion = singleQuestion.timePerQuestion;
return setplayerQuestionToDisplay({playerQuestionToDisplay:questionPage})
}
}
catch(error){
console.log(error)
}
}
getAllUserFromIndexDb();
return function cleanup() {
setplayerQuestionToDisplay({playerQuestionToDisplay:{}})
}
},[history.location.pathname]);
问题在于,只有一个按钮单击(代码段三)( displaySingleQuestion()
)会触发整个功能并重定向到 {{ 1}} 页面,但是在这种新的方式下,直到重新加载页面后才设置状态,我尝试调试问题,发现单击按钮时我发现了代码段最后执行两次,因此在运行第四代码段时,它处于承诺状态,直到页面重新加载发生为止,该组件的状态为 undefined
感谢您的阅读,对于解决此问题,我将不胜感激。