【问题标题】:How to map an API with Typescript in ReactJS?如何在 ReactJS 中使用 Typescript 映射 API?
【发布时间】:2022-01-20 13:38:10
【问题描述】:

我是 Typescript 的新手,我必须从 API 获取书籍列表。我的教授给了我 javascript 中的代码来执行此操作,但我必须在 typescript 中执行此操作并做出本机反应。

获取api:

import axios from 'axios';

const api = axios.create({
    baseURL: "https://hn.algolia.com/api/v1"
});

export default api;

列表组件:

import React, { Component } from "react";
import './List.css';

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

    render() {
        const apiData = this.props;

        return (
            <div className="List">
                {apiData?.map(item => (
                <div className="Livro">
                    <h3> {item.name}</h3>
                    <p> {item.authors.join(',')}</p>
                    <p><a href={item.url} target='_blank' rel="noreferrer"> {item.url}</a></p>
                </div>
                ))}
            </div>
        );
    }
}

export default List;

我将如何调用 List 组件的示例:

import React, {Component} from 'react';
import List from '../../components/list'
import api from '../../_config/api';
import './Welcome.css';

class Welcome extends Component {
  
  constructor(props){
    super(props);
    this.state = {sectionData:props.sectionData}
    this.filterList = this.filterList.bind(this);
    this.fetchData = this.fetchData.bind(this);
  }
  
  async fetchData(value) {

    const response = await api.get('/books?name='+value)

    this.setState({sectionData:response?.data})
    
  }

  async componentDidMount(){
    this.fetchData('');
  }

  render() { 
    const {sectionData} = this.state;


    return (
        <div className="Welcome">
             <List data={sectionData}/>
        </div>
      );
      
  }

}

export default Welcome;

仅在 Javascript 中有效的部分代码:

return (
            <div className="List">
                {apiData?.map(item => (  // error here
                <div className="Livro">
                    <h3> {item.name}</h3>
                    <p> {item.authors.join(',')}</p>
                    <p><a href={item.url} target='_blank' rel="noreferrer"> {item.url}</a></p>
                </div>
                ))}
            </div>
        );

我尝试在打字稿中以相同的方式执行此操作,但它返回此错误:

类型错误:属性“map”不存在于类型“Readonly & Readonly'。

有没有什么办法可以解决这个错误,或者不用map()来映射一个API?

【问题讨论】:

  • 您似乎假设 props 将是一个数组,但事实并非如此,但如果没有 minimal reproducible example,这并不完全清楚。

标签: javascript reactjs typescript react-native mapping


【解决方案1】:

尝试为您的List 组件创建一个接口,并将该接口放在您的组件上,如下所示。

interface IListProps {
 apiData?: { name: string, authors: string[], url: string }[];
}

interface IListState {}

class List extends Component<IListProps, IListState> {
// your code...
}

我还看到Welcome 组件的render 内的List 组件上的props 是错误的。

interface IWelcomeProps {
  sectionData?: { name: string, authors: string[], url: string }[];
}

interface IWelcomeState {}

class Welcome extends Component<IWelcomeProps, IWelcomeState> {  
  // your code...

  render() {
    const { sectionData } = this.state; 
    return (
        <div className="Welcome">
             <List apiData={sectionData}/> // replace data by apiData
        </div>
      );
      
  }

}

你可以找到更多关于如何使用接口here的信息。

【讨论】:

  • 我现在试过了,但是不行,不知道为什么。
  • 这很好,但是您的状态界面毫无意义。它可以与它扩展的 Props 接口互换。
  • @AluanHaddad 谢谢你的建议。我会编辑答案。
【解决方案2】:

从 xZliman 的想法开始,我进行了研究,执行此操作时没有出错:

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

    render() {
        const apiData = this.props as {name: string, authors: string[], url: string}[]; // Here is the change

        return (
            <div className="List">
                {apiData.map(item => (
                <div className="Livro">
                    <h3> {item.name}</h3>
                    <p> {item.authors.join(',')}</p>
                    <p><a href={item.url} target='_blank' rel="noreferrer"> {item.url}</a></p>
                </div>
                ))}
            </div>
        );
    }
}

export default List;

也许这不是一个好的解决方案,但它可以作为一种解决方法完成工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-20
    • 2020-06-13
    • 2020-09-18
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    相关资源
    最近更新 更多