Home > Software engineering >  Reactjs - Can't call setState on a component that is not yet mounted
Reactjs - Can't call setState on a component that is not yet mounted

Time:07-16

I am getting an error can't call setState on a component that is not yet mounted. Weirdly the Udemy video i am following does not get this error. I tried to check if this is due to v5 and v6 routing issue but found no solutions. What I am trying to do here is to pull specific user data when i click on a profile name or search a username. Current View But the results are not showing for every this.state calls

import React,{Component} from "react";
import withRouter from '../withRouter';
import Repose from "./Repose";
class Specific extends Component{
    constructor(props){
        super(props);
        this.state ={ user:[]};
        const FetchUser = async(user)=>{
            const API_Call=await fetch(`https://api.github.com/search/users/${user}`)
            const data= await API_Call.json();
            return {data}
        }
        FetchUser(props.params.login).then((res)=>{
            if(!res.data.message){
                this.setState({user:res.data})
            }
        })
    }
    
    Data () {
        if(this.state.user.login===0){
            return(<i>No user with given username{this.props.params.login}</i>)
        }else {
            return(
                <center>
  <section className="Specific">
    <div className="main" id="main">
    <div className="container">
      <div className="row">
      <div className="col-lg-12 col-md-12">
        <div className="SUsersData">
        <i className="fas fa-heart  NotFave"></i><h4>Name :<i className="bl">{this.state.user.name}</i>   </h4>
        <img src={this.state.user.avatar_url}alt="" />
          <h4>followers :<i className="bl"> {this.state.user.followers} </i>  </h4> 
          <h4>location :<i className="bl"> {this.state.user.location} </i> </h4>
          <Repose user={this.props.params.login}/>

        </div>
        </div>
      </div>
    </div>
    </div>
    
  </section>
</center>
            );
        }
    }

    render(){
        return(
            <React.Fragment>
                {this.Data()}
            </React.Fragment>
        );
    }
}

export default withRouter(Specific);

CodePudding user response:

The constructor is called before the component is mounted, and therefore you may end up calling setState early. Generally you should not preform data fetching in the constructor of a react component. See more here: https://stackoverflow.com/a/55182747/5574617

I would reccomend you refactor your fetchUser out into the componentDidMount() lifecycle method where you can from there safely call setState


class Specific extends Component{
  constructor(props){
    super(props);
    this.state ={ user:[]}
  }

  async componendDidMount() {
    const FetchUser = async(user)=>{
      const API_Call=await fetch(`https://api.github.com/search/users/${user}`)
      const data= await API_Call.json();
      return {data}
    }
    FetchUser(this.props.params.login).then((res)=>{
      if(!res.data.message){
        this.setState({user:res.data})
      }
    })
  }

CodePudding user response:

There is also the fact that class based components have fallen out of use in favor of functional components and hooks your component implemented with the new style would be:

const Specific = ()=>{

const { login } = props.params; //grab props 


const FetchUser = async(user)=>{
      const API_Call=await fetch(`https://api.github.com/search/users/${user}`)
      const data= await API_Call.json();
      return {data}
    } //this function should really be in a different file

const [user, setUser] = useState([]); //declare the state and function used to edit it
useEffect(()=>{
  let user = FectchUser(login); //this function doesnt return a Promise, so u cant use "then"
  setUser(user);
      
    }, [login])
    
    return (
    <>
    ...rest of jsx
    </>);
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

  • Related