Как получить данные состояния сразу после их изменения с родительского на дочерний в React?

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть следующее приложение react с несколькими компонентами. У меня есть два дочерних компонента (card и modal) и один родительский компонент (board). Просто я нажимаю на карточку в компоненте card и отправляю идентификатор карты компоненту board. У компонента Board есть данные API. Он фильтрует данные API с идентификатором карты, поступающим из компонента card, и отображает соответствующие данные в модальном компоненте.

Проблема в том, что модальный компонент загружает пустой массив, который является ProjectData в начале, еще до нажатия на карточку. Тогда я не могу получить какой-либо элемент внутри массива и говорю «Не удается получить свойство undefined» для каждого вызова массива.

Компонент Card:

 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>
    )
  }
}
  

Компонент платы:

 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}
       />
    )
  }
}
  

Модальный компонент:

 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
      )
    }
}
  

Комментарии:

1. @DavidJohns Как сказал Толле, вы должны изменить projectAllData массив состояний на объект include projectName .

2. @kkangil дело в том, что я получаю ProjectName после двойного нажатия на карточку, что означает, что состояние обновляется во второй раз

3. где ваша функция щелчка, которая получает projectName результат? getPojectId Функция с axios получает projectName результат, но вы нигде не используете приведенный выше код.

4. @kkangil вы можете увидеть onclick метод в div в компоненте Card. Он запускает sendCardId метод с идентификатором проекта и улавливает его в компоненте платы с getProjectId помощью метода. Он вызовет API и отправит все данные проекта, в том числе projectName в модальный компонент.

5. @DavidJohns хорошо, но у projectAllData нет projectName , это массив. почему вы дважды вызываете setState в getPojectId ? просто используйте один раз.

Ответ №1:

используйте setState один раз.

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

И установите объект состояния инициализации, а не массив

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

или это может быть лучше.

 this.state = {
  currentID: null,
  projectAllData: undefined,
  open: false,
};
render(){
  return(
    <>
    {
      this.state.projectAllData amp;amp; (
        <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}
      />
    </>
  )