Выборка данных из api в componentDidMount возвращает значение null

#javascript #reactjs #api

#javascript #reactjs #API

Вопрос:

Я пытаюсь извлечь данные в componentDidMount методе жизненного цикла react, но у меня ничего не получается.

мой метод:

   componentDidMount() {
    const { taskId } = this.props
    getTask(taskId)
    .then(data => {
        console.log(data);
      this.setState({task: data});
    })
  }
 

мой api — это:

   export const getTask = (unique_id) =>  {
  console.log(unique_id)
    return fetch('https://punctual-backend-staging.herokuapp.com/api/v1/homeowner_tasks/'  unique_id).then(res => { 
    return res.json();
    });
  };
 

это весь мой компонент:

 import React, { Component } from 'react'
import { getTask } from '../../modules/clients';
import ClientTaskShow from '../../components/tasks/ClientTaskShow'

class ClientTaskShowContainer extends Component {
  constructor(props) {
    super(props)

    this.state = {
      messageModalOpen: false,
      selectedPartnerId: null,
      task:{}
    }
  }

  componentDidMount() {
      console.log("hello")
    const { taskId } = this.props
    getTask(taskId)
    .then(data => {
        console.log(data);
      this.setState({task: data});
    })
  }
  render() {
    const taskSelected = this.state.task;
    console.log(taskSelected)
        return (
            <ClientTaskShow 
                task={taskSelected}
            />
        )   
  }
}

export default ClientTaskShowContainer;
 

код, откуда вызывается clienttaskShowContainer:

 import React from 'react'
import Head from 'next/head'
import Layout from '../../components/Layout'
import ClientTaskShowContainer from '../../containers/tasks/ClientTaskShowContainer'
import requireAuth from '../../lib/requireAuth'

const ClientTasksShow = ({ query }) => {
  const { taskId } = query
  return (
    <Layout fluid fullHeight clientTaskHeader='true'>
      <Head>
        <title>Client Task Details | Punctual</title>
      </Head>
      <ClientTaskShowContainer taskId={taskId} />
    </Layout>
  )
}

ClientTasksShow.getInitialProps = async ({ query }) => ({
    query
  })

export default requireAuth(ClientTasksShow)
 

Я думаю, что он даже не попадает в API. Хотя это произошло, как только я перезапустил сервер, но не снова. Я не в состоянии воспроизвести проблему.
На некоторых сайтах, которые я обнаружил, что мы должны использовать .then для вызова API, другие говорят, что мы не можем передать периметр при вызове API в componentDidMount. Каково точное решение для этого. Пожалуйста, помогите. Заранее спасибо.

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

1. Действительно ли это возвращается null ? Если да, возвращает ли API вообще JSON? Действительно ли клиент обращается к правильному API? fetch Отклоняет (прикрепляет .catch к нему!)?

2. Я предполагаю, что даже comonentDidMount не работает или вызывается

3. Откуда ты это знаешь? "hello" Регистрируется ли он?

4. нет, он не зарегистрирован

5. можете ли вы указать значение для unique_id, которое было передано в api в качестве параметров запроса

Ответ №1:

Этот код работает

//Вызывающий компонент

 import React from "react";
import CallComp from "./CallComp";
import ReactDOM from "react-dom";

function App() {
  return (
    <div className="App">
      <CallComp taskId={"7693fbf81a33"} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
 

// Дочерний компонент

 import React, { Component } from "react";
import ClientTaskShow from "./ClientTaskShow";

class ClientTaskShowContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      task: {}
    };
  }

  componentDidMount() {
    const { taskId } = this.props;
    fetch(
      `https://punctual-backend-staging.herokuapp.com/api/v1/homeowner_tasks/${taskId}`
    )
      .then(response => response.json())
      .then(data => this.setState({ task: data }))
      .catch(error => console.log("the error is", error));
  }
  render() {
    const taskSelected = this.state.task;
    console.log("task selected is ", taskSelected);
    return (
      <div>
        {Object.keys(taskSelected).length ? (
          <ClientTaskShow task={taskSelected} />
        ) : (
          <div>No data to show</div>
        )}
      </div>
    );
  }
}

export default ClientTaskShowContainer;
 

// Демонстрационный ClientTaskShow

 import React from "react";

const ClientTaskShow = ({ task }) => {
  return <h1>{task.unique_code}</h1>;
};

export default ClientTaskShow;
 

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

1. Я добавил демонстрационное ClientTaskShow для вашей справки, вы можете использовать любой компонент, который принимает данные задачи из api. Вам также необходимо изменить path для ClientTaskShow.

2. например, вы использовали дополнительный div, то же самое, если я использую, это работает, но при использовании моего компонента это не так

3. В react всегда должен быть один родительский элемент (корневой элемент), вы можете использовать <Fragment /> или просто <></>, чтобы избежать переноса <div> для решения этой проблемы.

4. Спасибо, чувак, это было очень полезно

Ответ №2:

На самом деле это работает

введите описание изображения здесь

console.log(data) возвращает сообщение об ошибке из api

Ответ №3:

Вы должны вернуть обещание из функции, чтобы узнать, разрешен запрос api или нет

попробуйте это:

 export const getTask = (id) => {
    return new Promise(function (resolve, reject) {
        fetch('https://punctual-backend-staging.herokuapp.com/api/v1/homeowner_tasks/'   id).then((res) => {
            resolve(res.json())
        })
    });
}
 

И вызывайте так:

 componentDidMount() {
    getTask(1).then((data)=>{
        console.log(data);
    });  
}
 

Вы можете заменить параметры своим идентификатором

Надеюсь, это поможет.