React组件调用setState后不更新:仅前端服务重启生效,刷新页面即失效
问题根因
问题核心是异步更新的props没有同步到子组件state,具体逻辑如下:
- 父组件Post的
state.user是异步获取的(比如从登录态接口、本地存储读取都需要时间),页面刷新后父组件第一次渲染时,user还没有加载完成,传给CommentForm的user是undefined - CommentForm只会在constructor初始化时,把传入的
props.user赋值给自己的state.user,后续父组件user加载完成后传入新的props,子组件的state.user不会自动更新,会一直保留初始的undefined - 你在判断用户是否点赞时,对比的是
like.user == this.state.user,该判断永远返回false,所以liked状态一直是初始值false,点赞图标自然不会切换 - 热更新时功能正常,是因为React热重载会保留父组件已经加载完成的
user状态,CommentForm初始化时拿到的props.user就有有效值,判断逻辑可以正常执行
解决方案
方案1(更推荐):直接使用props.user,不存储到子组件state
user本身是父组件传递的属性,子组件不需要额外存一份到自己的state,直接在所有用到的地方读取this.props.user即可:
- 修改constructor,移除state里的
user字段 - 调整
componentDidMount里的判断逻辑:
componentDidMount () { axios.get(`http://localhost:3002/p/likes/${this.state.post}`).then(res=>{ const liked = res.data.some(like => like.user === this.props.user) this.setState({likes: res.data, liked}) }) }
- 调整
handleLike里的判断逻辑:
handleLike(event) { axios.post('http://localhost:3002/p/like', {...this.state, user: this.props.user}).then(res=>{ const liked = res.data.likes.some(like => like.user === this.props.user) this.setState({likes: res.data.likes, liked}) }) }
只要父组件的user更新,子组件会自动重新渲染,所有用到props.user的地方会同步最新值。
方案2:监听props变化手动更新state
如果确实需要把user存在子组件state里,需要添加componentDidUpdate生命周期监听props变化,同步更新state并重新拉取点赞状态:
componentDidUpdate(prevProps) { // 只有user发生变化时才执行逻辑,避免死循环 if (prevProps.user !== this.props.user) { this.setState({user: this.props.user}, () => { // state更新完成后重新拉取点赞列表 axios.get(`http://localhost:3002/p/likes/${this.state.post}`).then(res=>{ const liked = res.data.some(like => like.user === this.state.user) this.setState({likes: res.data, liked}) }) }) } }
内容的提问来源于stack exchange,提问作者Raphael Morgan
相关产品推荐
相关产品推荐

