如何解决在检索数据库数据之前反应渲染
我正在编写一个应用程序,用于拉取我的 GitHub 存储库并显示其中的某些信息(描述等)。该应用程序设置为如果我没有“初始化”(意味着我还没有发送帐户),那么我将被迫进入“CreateAccount”页面。 “初始化”的状态保存在本地存储中。但是,如果其他人想要查看该应用程序,它们将不会被“初始化”,因此我需要再次检查以查看数据库中是否有任何内容(每个存储库的记录)。如果是这样,那么查看器应该被“初始化”并发送到主页。所有这些都在 App 组件中完成:
const App = () => {
const setupCtx = useContext(SetupContext);
const devCtx = useContext(DevDataContext);
// variable to control routing
let initialized = null;
if (localStorage.getItem("jtsy-signin") === "true") {
initialized = true;
} else {
API.findRepo()
.then((repo) => {
console.log('APP found 1 repo',repo)
if (repo) {
initialized = true
localStorage.setItem('jtsy-signin','true')
console.log('1 REPO initialized',initialized)
} else {
initialized = false;
}
})
}
useEffect(() => {
if (initialized) {
console.log('APP useEffect signin=true,redirect to Home page');
if (localStorage.getItem('jtsy-login') === 'true') {
setupCtx.updateLoggedIn();
}
// console.log('APP devUpdated',setupCtx.state.devUpdated)
if (setupCtx.state.devUpdated) {
API.getActiveDevData().then((activeDevData) => {
// console.log('APP activeDevData',activeDevData.data);
const developerData = {
developerLoginName: activeDevData.data.developerLoginName,developerGithubID: activeDevData.data.developerGithubID,repositories: activeDevData.data.repositories,fname: activeDevData.data.fname,lname: activeDevData.data.lname,email: activeDevData.data.email,linkedInLink: activeDevData.data.linkedInLink,resumeLink: activeDevData.data.resumeLink,active: true
}
console.log('APP after DB call',developerData)
devCtx.updateDev(developerData)
setupCtx.updateInitialized();
setupCtx.updateDevUpdated(false)
})
}
};
},[setupCtx.state.devUpdated])
return (
<div className='App'>
<React.Fragment>
<Router>
<Switch>
{console.log('IN APP SWITCH initialized',initialized)}
{initialized ? (
<Route exact path="/" component={Home} />
) : (
<Route exact path="/" component={CreateAccountComp} />
)}
<Route exact path="/contact" component={Contact} />
<Route exact path="/about" component={About} />
<Route exact path="/developer" component={Developer} />
<Route exact path="/login" component={LoginModal} />
<Route exact path="/logout" component={logoutModal} />
<Route exact path="/signin" component={CreateAccountComp} />
<Route exact path="/settings" component={Settings} />
<Route component={NoMatch} />
</Switch>
</Router>
</React.Fragment>
</div >
);
};
导出默认应用;
变量 'initialized' 控制是呈现主页还是 CreateAccount 页面。如代码所示,首先检查本地存储,如果那里有值,则将 'initialized' 设置为 'true' 并呈现主页。这工作正常。但是,如果本地存储中没有值,我接下来调用 findRepo(),它会在 Mongo 数据库中执行 .findOne()。然后,相应地设置 'initialized' 的值。从数据库获得响应的延迟太长。如果本地存储中没有值,则在呈现时初始化为 'null',因此应用程序始终会转到“CreateAccount”页面。我可以看出数据库调用正在正确响应并且初始化设置为“true”,但为时已晚(CreateAccount 已呈现)。
我尝试将数据库调用放在 useEffect 和单独的 useEffect 中,但都没有奏效。我需要更好的方法来完成这项工作。
解决方法
因此,我对您的代码进行了一些检查,并提出了一个解决方案,可以在状态中添加加载标志,并在我们等待任何类型的更新时使用它来呈现加载屏幕。
在等待更新时,您可以将此加载屏幕设为您想显示的任何内容。
以下是所有在 App.js
// add isLoading flag to state
const [state,setState] = useState(
{
loggedIn: null,sync: false,initialized: null,isLoading: true
}
)
在调用 setState
时,将 isLoading 标志更新为 true。
// line 55 in App.js
setState({
...state,initialized: true,isLoading: false
})
// line 75
setState({
...state,isLoading: false
})
// line 103
setState({
...state,initialized: false,isLoading: false
})
然后是 return
更新。
{state.isLoading && <div>Loading...</div>}
<Route exact path="/" component={state.initialized ? Home : CreateAccountComp} />
通过这些更改,加载屏幕将在我们等待 initialized
的任何类型更新时显示。然后主屏幕将在更新为 true 或创建帐户页面是否更新为 false 时显示。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。