Búsqueda de sitios web

reactjs - React + Typescript: ¿Cómo definir una interfaz para un arreglo que se llena desde componentDidMount?


Estoy explorando React y Typescript y me quedé atascado en un problema sobre cómo definir una interfaz para un arreglo donde se almacenan datos de una API.

Esto es lo que tengo:

interface IState {
  loadingData: boolean;
  apiData: Array<string>;
}

class Contact extends Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    this.state = {
      loadingData: true,
      apiData: []
    };
  }

  componentDidMount() {
    const apiUrl = 'http://jsonplaceholder.typicode.com/users';
    fetch(apiUrl)
      .then((response) => response.json())
      .then((data) => {
        console.log('This is your data', data);
        this.setState({ loadingData: false, apiData: data });
      })
      .catch(error => console.log('error: ', error));
  }
  ...

Después de ejecutar este código, sin embargo, recibo el siguiente error:

Error: Objects are not valid as a React child (found: object with keys {id, name, username, email, address, phone, website, company}). If you meant to render a collection of children, use an array instead.
    in div (at Contact.tsx:39)
    in div (at Contact.tsx:33)
    in Contact (created by Context.Consumer)
    in Route (at Main.tsx:26)
    in div (at Main.tsx:23)
    in div (at Main.tsx:16)
    in Router (created by HashRouter)
    in HashRouter (at Main.tsx:15)
    in Main (at src/index.tsx:9)

¿Cuál es la clave para configurar correctamente una interfaz para un arreglo?

EDITAR: Agregando la función render:

render() {
    return (
      <div>
        <div>
          <h5>API Data</h5>
          {this.state.loadingData ? (
              'Loding data...'
            ) : (
              this.state.apiData
            )
          }
        </div>
      </div>
    );
  }

Respuesta #1

No puedes renderizar un array en React.

{this.state.loadingData ? (
   'Loding data...'
  ) : (
    this.state.apiData 
     && this.state.apiData.map(item => <p key={item.id}>{item.name}</p>
  )
}

this.state.apiData && this.state.apiData.map comprobará si apiData existe (no es falso, esto no te protegerá de que sea de un tipo incorrecto) y luego ejecutará la llamada a map.

Y necesitas actualizar tu interfaz

interface IState {
  loadingData: boolean;
  apiData: ApiData[];
}

interface ApiData {
  id: string
  name: string
  ...
}

Artículos relacionados