首页 > 解决方案 > React .map 给出错误以渲染从 fetch 调用收到的 JSON

问题描述

我正在学习 React,并且正在使用 fetch API 向 HTTP 服务器发送 get 请求。我能够成功检索 JSON。代码如下:-

componentDidMount() {
                console.log("Send GET request to Go server")
                fetch("http://192.168.121.106:8080/site", {
                        method: "GET",
                        headers: {
                                Accept: "application/json",
                                "Content-Type": "application/json",
                                'Access-Control-Allow-Origin': '*',
                        }
                }).then(response => {
                        if(response.status === 200) {
                                response.text().then(data => {
                                        this.setState({
                                                siteData : data
                                        });

                                });
                        }
                })
        }

我想以表格的形式呈现这个 JSON。siteData 是一个对象。这就是我的渲染功能:-

render() {

            const siteVar =  JSON.stringify(this.state.siteData);

            return (
                    <React.Fragment>
                            <table className="table">
                                    <thead>
                                            <tr>
                                                    <th >S. NO.</th>
                                                    <th >NAME</th>
                                                    <th >AGE</th>
                                            </tr>
                                    </thead>
                                    <tbody>

                                            { (this.state.siteData).map(site =>
                                                    <tr>
                                                            <td> {site.name} </td>
                                                            <td> {site.age} </td>
                                                    </tr>

                                            )}
                                    </tbody>
                            </table>
                    </React.Fragment>
            )
    }
}

使用此代码,我收到一个错误:

this.state.siteData.map 不是函数

我在这里做错了什么?

这是 JSON 的样例:-

{
  "1": {
    "name": "Alice",
    "age": "23",
  },
  "2": {
    "name": "Bob",
    "age": "25",
  }
}

标签: reactjs

解决方案


您收到错误的原因是因为您试图mapobject. 您需要将您的object变成一个array以便能够使用map并将其存储在您的中state

const response = {
  "1": {
    "name": "Alice",
    "age": "23",
  },
  "2": {
    "name": "Bob",
    "age": "25",
  }
}

const responseAsArray = Object.keys(response)
  .map(key => {
    return {
      siteNum: key,
      ...response[key]
    }
  })

console.log(responseAsArray)

回到您的代码,它看起来如下所示:

componentDidMount() {
  fetch(...)
    .then(response => {
      // Note the use of `.json()` here
      // if your API returns some JSON as a response
      // use this instead of `text()` since it will
      // parse a JSON response into native JavaScript objects
      if (response.status === 200) {
        return response.json()
      }
      // TODO: handle errors appropriately
    })
    .then(json => {
      const siteData = Object.keys(json).map(key => {
        return { siteNum: key, ...json[key] }
      })
      this.setState({ siteData })
    })
    .catch(/* TODO: handle errors appropriately */)
}

这是一个工作示例:

class App extends React.Component {
  state = { siteData: [] };

  componentDidMount() {
    fakeFetch()
      .then(response => {
        if (response.status === 200) {
          return response.json();
        }
      })
      .then(data => {
        const siteData = Object.keys(data).map(key => {
          return { siteNum: key, ...data[key] };
        });
        this.setState({ siteData });
      })
      .catch(console.error);
  }

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

    if (siteData.length === 0) {
      return "Loading";
    }
    return (
      <table>
        <thead>
          <tr>
            <th>S. NO.</th>
            <th>NAME</th>
            <th>AGE</th>
          </tr>
        </thead>
        <tbody>
          {siteData.map(({ siteNum, name, age }) => (
            <tr key={siteNum}>
              <td>{siteNum}</td>
              <td>{name}</td>
              <td>{age}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
}

// NOTE:
// This assumes your API returns a JSON response
// that looks like like this: 
// {"1":{"name":"Alice","age":"23"},"2":{"name":"Bob","age":"25"}}

function fakeFetch() {
  return Promise.resolve({
    status: 200,
    json: () => {
      return {
        "1": {
          name: "Alice",
          age: "23"
        },
        "2": {
          name: "Bob",
          age: "25"
        }
      };
    }
  });
}

ReactDOM.render(
  <App />,
  document.getElementById("app")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>


推荐阅读