setState function not working In react when called inside componentDidMount

32 views Asked by At

I am importing a json file into my react app for the data and using setState function as shown in the code below

import ruleSets from './db.json'
class App extends React.Component{
  componentDidMount(){
    ruleSets.map((element)=>{
      if(element.phase ==="post_auth"){
        this.setState({
          postAuthRuleSets: element,
        })
      }
      else if(element.phase === "pre_auth"){
        this.setState({
          preAuthRuleSets:element
        })
      }
    })
  }


  constructor(props,context){
    super(props,context);
    this.state={
      postAuthRuleSets:null,
      preAuthRuleSets:null
    }
  }

  render(){
    return(
    <div>
      <h1>hello</h1>
    {this.postAuthRuleSets.rules?.length>0 ? 
    this.postAuthRuleSets.rules.map((element) => <h1> {element.id}</h1>):
    <h1>not fetching data</h1>}
    </div>)
  }
}
export default App;

but error is showing in the console because the variables I'm looping through are pointing null which means setState is not working.

How should I go about this?

1

There are 1 answers

0
Nicholas Tower On
{this.postAuthRuleSets.rules?.length>0

This is accessing a property that does not exist: this.postAuthRulesSets. It should be accessing the state, as in this.state.postAuthRulesSets. Also keep in mind that it will be null during the first render, so make sure to use optional chaining at all necessary spots:

{this.state.postAuthRuleSets?.rules?.length > 0

Another improvement you can do is to move the logic out of of componentDidMount and into the constructor. Everything you're doing is synchronous, so there's no need to wait until after the component is already mounted. This change will mean you only need to render once instead of twice, and there will be no possibility of this.state.postAuthRuleSets being null

constructor(props,context){
  super(props,context);
  this.state={
    postAuthRuleSets: ruleSets.find(element => element.phase === "post_auth"),
    preAuthRuleSets: ruleSets.find(element => element.phase === "pre_auth")
  }
}