【问题标题】:React components don't update upon setState if I've reloaded the page since editing the files如果我在编辑文件后重新加载了页面,则 React 组件不会在 setState 上更新
【发布时间】:2022-01-08 22:50:51
【问题描述】:

我发现了很多关于当有人设置状态时 React 组件不更新的问题,但大多数答案似乎都在说做我正在做的事情。事实上,我所做的工作确实有效——但前提是我在上次重新加载或更改页面后编辑并保存了我的一个 React 文件(并因此重新启动了前端服务器)。基本上,我的意思是,如果我重新加载页面,这不起作用,如果我点击一个链接(例如,到 /messages),它就不起作用。

我要做的是根据某人是否喜欢帖子显示不同的喜欢符号(填充或轮廓)。这是 render 方法中的 jsx:

{this.state.liked ? <Recommend onClick={this.handleLike}/> : <RecommendOutlined onClick={this.handleLike}/>}

"liked" 在构造函数中设置为 false,然后在 1) componentDidMount() 和 2) like/unlike 函数中更新。以下是那些:

componentDidMount () {
  axios.get(`http://localhost:3002/p/likes/${this.state.post}`).then(res=>{
    console.log(res.data)
    let liked = false;
    for (let like of res.data) if (like.user == this.state.user) liked = true;
    this.setState({likes: res.data, liked})
  })
}

handleLike(event) {
  axios.post('http://localhost:3002/p/like',this.state).then(res=>{
    let liked = false;
    for (let like of res.data.likes) if (like.user == this.state.user) liked = true;
    this.setState({likes: res.data.likes, liked})
  })
}

它们都使用setState(),所以组件应该自动重新渲染。 handleLike() 绑定在构造函数中(意思是我做了this.handleLike = this.handleLike.bind(this);),所以应该调用它(确实如此)。

而且,最令人困惑的是,这确实有效。只是在特定的场景中。所以我不知道发生了什么。它在我更新文件后工作,然后如果我重新加载页面,它会将所有帖子显示为不喜欢(即使我所做的任何控制台日志显示它们是否真的被喜欢)。

如果我遗漏了什么,这里是整个组件:

import React, {Component} from "react";
import axios from 'axios';
import { Grid } from "@mui/material";
import {Recommend, RecommendOutlined} from '@mui/icons-material';

import style from './style.css'

axios.defaults.withCredentials = true;

class CommentForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            post: props.post, likes: [],  liked: false, comment: '', user: props.user
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleLike = this.handleLike.bind(this);
    }
    componentDidMount () {
        axios.get(`http://localhost:3002/p/likes/${this.state.post}`).then(res=>{
            console.log(res.data)
            let liked = false;
            for (let like of res.data) if (like.user == this.state.user) liked = true;
            this.setState({likes: res.data, liked})
        })
        //this.setState({likes: ['o','e','raphaelmorgan'],liked: true})
    }
    handleChange(event) {
        this.setState({[event.target.name]: event.target.value});
    }
    handleSubmit(event) {
        event.preventDefault();
        axios.post('http://localhost:3002/p/comment',this.state)
          .then(res=>{
              console.log(res.data)
              console.log(event.target);
              if (res.data.status == 'success') this.setState({comment: ''})
          });
    }
    handleLike(event) {
       console.log('liking post')
        axios.post('http://localhost:3002/p/like',this.state).then(res=>{
            let liked = false;
            for (let like of res.data.likes) if (like.user == this.state.user) liked = true;
            this.setState({likes: res.data.likes, liked})
        })
    }
    render() {
        let state = this.state;
        console.log(state.liked)
        return (
            <Grid container direction="row" alignItems="center">
                <Grid item>{this.state.liked ? <Recommend onClick={this.handleLike}/> :
                  <RecommendOutlined onClick={this.handleLike}/>}</Grid>
                <Grid item><form onSubmit={this.handleSubmit}>
                    <input name="comment" type="text" onInput={this.handleChange} 
                      placeholder="Comment" value={this.state.comment}/>
                </form></Grid>
            </Grid>
        )
    }
}

export default CommentForm;

更新: 显然问题出在分配道具的某个地方。 props.user 显然只是自服务器启动以来页面未重新加载时的一个东西。道具是从我的 Post 组件传入的,如下所示:

<CommentForm post={this.props.id} user={this.state.user}/>

不过,似乎“用户”属性实际上并没有被发送,因为它在评论表单上显示为未定义。

我有一个理论,我将对其进行测试,然后也许会回答我自己的问题。

【问题讨论】:

  • 您确定props.user 与来自后端的like.user 匹配吗?如果它是一个对象而不是字符串或数字,它永远不会与另一个对象相等。
  • 它们都是字符串。我只是 console.logged 他们两个以确保
  • 哦等等,没关系!只有当页面没有重新加载时才会出现这种情况,之后用户显示为未定义!但它在应该将它传递给用户的组件中工作,所以这就是问题所在。我现在会更新帖子。 ty @GabrielePetrioli
  • 不客气!

标签: javascript reactjs axios jsx mern


【解决方案1】:

感谢Gabriele的评论!

当我挂载&lt;Post&gt; 组件时,我使用axios.get() 将其状态设置为“user”和“loggedIn”。正如我们所知,这是异步的。因此,在将“用户”设置为状态之前,正在发送给孩子的道具(包括&lt;CommentForm&gt; 组件)。所以由于表单自己的axios调用是基于&lt;Post&gt;发送的“用户”,在组件挂载时是未定义的,当然like的用户是不会匹配的!

我通过更新&lt;CommentForm&gt;componentDidMount() 来修复它:

componentDidMount () {
  axios.get('http://localhost:3002/u/loggedin',{withCredentials: true}).then(res1=>{
    console.log(res1.data)
    if (!res1.data.loggedIn) return this.props.remove();
    this.setState({user: res1.data.user}) 
    axios.get(`http://localhost:3002/p/likes/${this.state.post}`).then(res2=>{
      let liked = false;
      for (let like of res2.data) if (like.user == res1.data.user) liked = true;
      this.setState({likes: res2.data, liked})
    })
  })
}

现在可以了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 2020-09-29
    相关资源
    最近更新 更多