David Johns
David Johns

Reputation: 1714

How to get state data right after changing them from parent to child in React?

I have the following react app with several components. I have two child components (card and modal) and one parent component (board). Simply I'm clicking on a card in card component and send the card ID to the board component. Board component has API data. It filters the API data with the card ID coming from card component and show the relevant data in modal component.

The problem is, modal component loads an empty array which is projectData at the beginning even before clicking on a card. Then I can't get any element inside the array and says "Can't get property undefined" for each array call.

Card component:

class TaskItem extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      more_state: false
    }
  }

  render() {

    const { sendCardId } = this.props;

    return(
      <div onClick={() => sendCardId(task.projectID)}>
      </div>
    )
  }
}

Board component:

class Taskboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentID: null,
      projectAllData: [],
      open: false,
    };
  }

  getPojectId = (projectId) => {
    this.setState({
      open: true,
      currentId: projectId
    });

    API.get('project/' + projectId)
      .then(({ data }) => {
        this.setState({
          projectAllData: data.response
        });
      })
      .catch((err) => {
        console.log("AXIOS ERROR: ", err);
      })
  }

  render(){
    return(
      <ProjectModal
          handleOpen={this.state.open}
          handleClosed={this.handleClose}
          projectID={this.state.currentId}
          projectData={this.state.projectAllData}
        />

      <Column
        key={key}
        index={index}
        title={key}
        tasks={columns[key]}
        getCardId={this.getPojectId}
       />
    )
  }
}

Modal component:

class ProjectModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            status: 'To do',
        };
    }

    render(){

      const { handleOpen, handleClosed, projectData, projectID } = this.props;
      return(
         <div>{projectData.projectName}</div
      )
    }
}

Upvotes: 0

Views: 45

Answers (1)

kkangil
kkangil

Reputation: 1746

use setState once.

getPojectId = (projectId) => {
    API.get('project/' + projectId)
      .then(({ data }) => {
        this.setState({
          projectAllData: data.response,
          open: true,
          currentId: projectId
        });
      })
      .catch((err) => {
        console.log("AXIOS ERROR: ", err);
      })
  }

And set init state object not array

this.state = {
      currentID: null,
      projectAllData: {projectName: ''},
      open: false,
    };

or This might be better.

this.state = {
  currentID: null,
  projectAllData: undefined,
  open: false,
};
render(){
  return(
    <>
    {
      this.state.projectAllData && (
        <ProjectModal
          handleOpen={this.state.open}
          handleClosed={this.handleClose}
          projectID={this.state.currentId}
          projectData={this.state.projectAllData}
        />
      )
    }

    <Column
      key={key}
      index={index}
      title={key}
      tasks={columns[key]}
      getCardId={this.getPojectId}
      />
    </>
  )

Upvotes: 1

Related Questions