【问题标题】:"State" undefined when trying to map fetched json data into React app尝试将获取的 json 数据映射到 React 应用程序时未定义“状态”
【发布时间】:2019-08-21 09:53:55
【问题描述】:

我正在从 wordpress api 获取数据。当我登录到控制台时,我看到了数据数组。在映射数据时,我收到一条错误消息“#myStateName.map 不是函数”。

我已经在 ReactJS.org、CSS Tricks 甚至 Stack Overflow 上寻找解决方案,但似乎没有任何效果

class WPHome extends Component {

  constructor(props) {
super(props);
this.state = {
  error: null,
  isLoaded: false,
  details: []
};
  }

  componentDidMount() {
fetch(API_URL)
  .then(res => res.json())
  .then(
    (result) => {
      console.log(result['0'])
      this.setState({
        isLoaded: true,
        details: [result]
      });
    },
    // Note: it's important to handle errors here
    // instead of a catch() block so that we don't swallow
    // exceptions from actual bugs in components.
    (error) => {
      this.setState({
        isLoaded: true,
        error
      });
    }

  )
}

render() {
const { error, isLoaded, details } = this.state;
if (error) {
  return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
  return <div>Loading...</div>;
} else {
  return (
    <div>
      {details.map(item => (
        <div key={item.id}>
          <p>{item.id}</p>
          <div>
            <img src={item._embedded['wp:featuredmedia']['0'].source_url} alt={item.id} />
          </div>
          <p>{item.content}</p>
          <hr />
        </div>
      ))}
    </div>
  );
}
  }

我希望我的数据正在传递到 HTML 块中,但我得到了一个 error

【问题讨论】:

  • 能否分享API的响应
  • Object { id: 2, date: "2019-08-05T11:51:22", date_gmt: "2019-08-05T11:51:22", guid: {…}, modified: "2019-08-05T12:51:42", modified_gmt: "2019-08-05T12:51:42", slug: "home", status: "publish", type: "page", … } WPHome.jsx:21
  • 您得到的响应结果是数组或对象,请使用console.log(typeof result)
  • 能否附上console.table(result) 的浏览器控制台截图
  • 上面写着“对象”console.log(typeof result)

标签: javascript reactjs api


【解决方案1】:

你没有在你的状态初始化details。在此处添加:

this.state = {
  error: null,
  isLoaded: false,
  result: [],
  details: [] // <- missing initialization
};

【讨论】:

  • 所以尝试注释掉componentDidMount()中的代码并检查是否会出现错误。如果不是问题出在result['0'] 内部 - 尝试检查您是否设置了此响应的好键。您还可以在渲染中添加console.log(typeof details, details) 以显示您在那里拥有的数据类型。
  • 注释掉后,错误消失。如果我console.log(result['0]),我会看到该集合中包含的所有数据。所以我不确定它的问题,可以吗?
  • 它说console.log(typeof details)未定义
【解决方案2】:

在构造函数的状态声明中添加以下内容

 this.state = {
  details:[],
  error: null,
  isLoaded: false,
  result: []
 }

这个错误可能是由于 this.state.details 在开始时未定义。

我还注意到,在您的提取请求中,您正在执行以下操作。

  this.setState({
    isLoaded: true,
    details: result['0']
  });

既然结果是一个数组,它不应该被设置为细节状态如下。

  this.setState({
    isLoaded: true,
    details: result
  });

【讨论】:

  • 是的。我的 API 返回 2 个数组数据集,但我想深入研究第一个,因此是“['0']”。我还定义了详细信息状态,但仍然抛出“details.map is not a function”错误。
  • details: [result]这一行,你仍然需要使用扩展运算符[...result],或者只使用第一个元素[result[0]],否则你会得到一个嵌套数组
【解决方案3】:

您的状态中似乎没有声明details 变量。

【讨论】:

    【解决方案4】:

    你能不能试着跑一下:

    render (
       <div>
              {
                details.map(item => (
                 <div key={item.id}>
                  <p>{item.status}</p>
                 </div>
             }
       </div>
    );
    

    然后发布情况如何?

    【讨论】:

    • 它不运行。它无法识别“详细信息”。
    • this.state.details
    • .map 函数仅在数组上可用。结果似乎不是您期望的格式(它是 {},但您期望的是 [])。或者,您可以使用如下内容: details = Array.from(props.data);或类似的...试试这个,让我知道这是否有效。
    【解决方案5】:

    请使用下面的 setState 语句,因为您的结果是一个对象

    this.setState({ isLoaded: true, details: [result] });
    

    【讨论】:

    • 它没有看到来自该州的任何数据。如果我映射&lt;p&gt;{item.id}&lt;/p&gt;,它会在渲染时显示一个空的&lt;p&gt;&lt;/p&gt;
    【解决方案6】:

    要遍历对象,请参考以下链接 - https://jsfiddle.net/oek6um0h/1/

    {Object.keys(details).length && Object.keys(details).map((item,k) => {
    return <any></any>
    }) || <p>nothing found</p>}
    
    

    map 用于数组而不是对象使用 map 我们需要使用 Object.keys() 哪个方法返回给定对象自己的可枚举属性名称的数组,其顺序与我们使用普通循环获得的顺序相同

    【讨论】:

    • 小提琴不显示任何结果。
    【解决方案7】:

    我终于明白了。虽然不得不使用 Axios,但它确实有效。

      constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      details: []
    };
    }
    
    componentDidMount(){
    axios
      .get(API_URL)
      .then(response => response.data.map(detail => ({
        image: `${detail._embedded['wp:featuredmedia']['0'].source_url}`,
          content: `${detail.content.rendered}`,
          id: `${detail.id}`
        }))
      )
      .then(details => {
        this.setState({
          details,
          isLoading: false
        });
      })
      .catch(error => this.setState({ error, isLoading: false }));
    }
    
    
    render() {
    const { isLoading, details } = this.state;
    
    return (
      <React.Fragment>
          {!isLoading ? (
            details.map(detail => {
              const { id, content, image } = detail;
              return (
                <div key={id}>
                  <p>{content}</p>
                  <div>
                    <img src={image} alt={id} />
                  </div>
                  <p>{content}</p>
                  <hr />
                </div>
              );
            })
          ) : (
              <p>Loading</p>
          )
          }
      </React.Fragment>
    )
      }
    

    【讨论】:

      【解决方案8】:

      您需要在constructor 中使用默认值而不是result 定义details

      constructor(props) {
          super(props);
          this.state = {
              error: null,
              isLoaded: false,
              details: [] // define missing
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-28
        • 2021-07-25
        • 2017-12-14
        • 1970-01-01
        • 1970-01-01
        • 2018-08-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多