javascript - React - 在渲染中更新内容的正确方法
问题描述
通常我对 ReactJS 的原理和渲染动态内容很有信心。不过,我真的可以得到一些帮助。
问题始于我有一个名为 Feed 的页面。此提要应显示从 API 获取的图像列表。
我需要通过作为标头传递的令牌来保护此 API。
在 App.js 中,这里是代码的相关部分,用于检查用户是否登录并限制对提要的访问,除非他们登录。令牌被保存到状态并作为道具传递给 Feed。
authenticate = () => {
const token = localStorage.getItem("token");
validateToken(token)
.then(() => {
this.setState({ authenticated: true, token: token });
})
.catch(() => {
this.setState({ authenticated: false, token: false });
})
}
render() {
let privateRoutes = null;
if (this.state.authenticated) {
privateRoutes =(
<div>
<Route exact path="/feed"
render={(props)=>{
return (
<Feed token={this.state.token}/>)}} />
<Route exact path="/profile/:username"
render={(props)=>{
return (
<Profile data={props}/>)}} />
</div>
);
}
然后在 Feed 中调用 API 以获取传入此令牌的图像。这就是问题所在,在 Feed 中,当我控制台日志“this.props.token”时,它在从 app.js 发送的内容之前一瞬间为空。
这意味着我无法在 componentDidMount 中调用 API,因为令牌最初为空。此外,这意味着我现在无法像在 render() 中那样设置帖子的状态。
这是提要代码:
render() {
const token = this.props.token;
let posts = []; // should be updated by below
if (token !== false) {
loadFeedForUser(token).then((response) => {
posts = response;
console.log(posts); // logs successfully
})
.catch(() => {
posts = [];
})
}
return (
<div className="App">
<div className="content">
<div className="feed">
{ Object.values(posts).map((post, i) => {
console.log(post);
return (
<Post/> // This does not run as posts still empty array
)
})}
在 HTML 中,for 循环对象永远不会运行,因为 posts 数组是空的,因为它没有注册为由 API 更新。
我的架构有什么问题?感觉一点都不好。
谢谢。
有人可以建议我在哪里可以改进吗?我只需要在经过身份验证后从 app.js 传递令牌,然后获取所有图像。
解决方案
在道具准备好之前,组件正在安装。这是一个非常常见的场景,这也是我更喜欢 hooks 的一个重要原因。要修复它,您应该使用componentDidUpdate
生命周期方法,例如
componentDidUpdate(prevProps, prevState, snapshot) {
if (props.token && props.token !== prevProps.token) {
makeApiCall(props.token)
}
}
您还需要有类似的逻辑,componentDidMount
以防它在挂载期间确实具有令牌值。否则它不会进行初始调用。
作为一个钩子,这就是所有需要的代码:
useEffect(() => {
makeApiCall(props.token)
}, [props.token])
推荐阅读
- flutter - 如何在 Flutter 小部件上进行点击事件而不实际点击它?
- python - 从 SQL 记录到 Python 二值化器
- java - 如何将外部非模块化 jar 添加到 java 9 模块化应用程序?
- android - Android:无法使用 Intent 在 Instagram 上分享照片
- dialogflow-es - 如何在对话流中使用 webhook?
- regex - 从前两个空格中排除一组字符
- html - 为什么样式没有应用于 html 中的文本
- php - Symfony 3.4:POST http 方法 Rest 的问题
- javascript - laravel 使用 ajax 上传图片
- python - 取消分解(取消分组)累积数据帧值