user9686855
user9686855

Reputation:

Rendering component with its state

I'm really confused now about lifecycle hooks. Here's my code:

App.js:

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      arrayOfComponents: []
    }
  }
  componentDidMount(){
  //i get the properties from the server which responds with the database's elements
    fetch('http://localhost:3001/')
    .then(res => res.json())
    .then(arrayOfData => this.setState({arrayOfComponents: arrayOfData}))
    .catch(err => console.log(err))
  }

  render() {
    console.log(this.state) //first returns empty array, after the mount returns the db's array of elements
    return (
      <div className="App">
        <Component name='First' id={1} componentsComponents={this.state.arrayOfComponents} />
      </div>
    );
  }
}

Component.js:

class Component extends React.Component{
    constructor(props){
        super(props);
        this.state={
            componentsComponents: []
        }
    }
    //here i was tried with componentDidMount, componentWillMount to set the
    //this.props.componentsComponents to this.state.componentsComponents
    //but it didn't work
    renderComponents = () => {
        if(this.state.componentsComponents.length){
            return this.state.componentsComponents.filter(c => c.inhertedFromId === this.props.id).map(c => {
                return <Component name={c.name} id={c.id} componentsComponents={this.props.componentsComponents} />
            })
        }
    }
    render(){
        return(
            <div>
                {this.renderComponents()}
            </div>
        )
    }
}

So what i want to do is to the components renders themselves, depending on the array they get from the App.js. But how to set the state before the render happens? Can i somehow ask the component to render again if it did mount? Or any other solutions?

Upvotes: 0

Views: 44

Answers (2)

Steve Banton
Steve Banton

Reputation: 2498

Bring Filter Up To App

Here it appears you are not calling renderComponents, and you are also trying to render a Component inside itself, which is difficult to reason about. Bring the renderComponents function up to App, and render the data using Component inside of App, and simply pass props down to a stateless Component, which may be a simpler solution to represent the data.

If a recursive call is indeed the best way to represent this data, may need to use getDerivedStateFromProps to move props into state on update, if you wish to store that data in state - something like:

static getDerivedStateFromProps(nextProps) {
  return {
    componentsComponents: nextProps.componentsComponents
  }
}

Added to Component.

Upvotes: 0

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

You can simply assign this.props.componentsComponents in constructor itself only.

constructor(props){
            super(props);
            this.state={
                componentsComponents: this.props.componentsComponents||[]
            }
        }

Upvotes: 1

Related Questions