通常我对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发送来的消息之前的一瞬间它为null。
这意味着我无法在componentDidMount中调用API,因为令牌最初为null。此外,这意味着我现在无法像在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传递令牌,然后获取所有图像。
答案 0 :(得分:1)
在准备好道具之前先安装组件。这是一个非常常见的情况,这是为什么我更喜欢钩子的重要原因。要修复它,您应该使用componentDidUpdate
生命周期方法,例如
componentDidUpdate(prevProps, prevState, snapshot) {
if (props.token && props.token !== prevProps.token) {
makeApiCall(props.token)
}
}
您还需要在componentDidMount
中具有类似的逻辑,以防万一安装过程中确实具有令牌值。否则它将无法进行初始呼叫。
作为一个钩子,这是所有需要的代码:
useEffect(() => {
makeApiCall(props.token)
}, [props.token])