【问题标题】:Error : Cannot read property 'map' of undefined错误:无法读取未定义的属性“地图”
【发布时间】:2014-09-02 13:59:30
【问题描述】:

我正在关注reactjs 教程,当
将值从一个组件的状态传递到另一个组件时,我一直遇到问题。

错误Cannot read property 'map' of undefined' 执行CommentList组件中的map函数时抛出。

CommentBox 传递到CommentList 时,什么会导致prop 变为undefined

// First component
var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function (comment){
      return <div><h1>{comment.author}</h1></div>;
    });
    return <div className="commentList">{commentNodes}</div>;
  }
});
// Second component    
var CommentBox = React.createClass({
   getInitialState: function(){
     return {data: []};
   },
   getComments: function(){
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        success: function(data){ this.setState({data: data}) }.bind(this),
        error: function(xhr, status, err){ console.error(url, status, err.toString()) }.bind(this)
      });
   },
   componentWillMount: function(){
      this.getComments()
   },
   render: function(){
      return <div className="commentBox">{<CommentList data={this.state.data.comments}/>}</div>;
   }
});

React.renderComponent( <CommentBox url="comments.json" />, document.getElementById('content'));

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这是我的问题所在:

    {props.users.map((item,index)=>(
        <div className="items" key={index}>
            <div className="text-center">
                <p className="fs-12">{item}</p>
            </div>
        </div>
    ))}
    

    然后我刚刚解决了添加此代码的问题。它就像 if 和 else 语句一样工作。

    { props.users ? props.users.map((item,index)=>(
            <div className="items" key={index}>
                <div className="text-center">
                    <p className="fs-12">{item}</p>
                </div>
            </div>
    )) : <p>Users is empty</p>}
    

    【讨论】:

      【解决方案2】:

      这对我有用。如果我使用 props.worktyp.map 它会抛出 map is not defined 的错误。

      //App.js
          const worktyp = [
                "Full-time",
                "casual",
                "part-time",
                "contract"
              ];
          
          function Main(props){
            return(
          <section>
            <p>This the main body</p>
            <ul style = {{textAlign:"left"}}>
              **{worktyp.map((work) => <li>{work}</li>)}**
            </ul>
          </section>
          
            );
              }
       function App() {
            return (
              <div className="App">
                <Header name="initial"/>
                **<Main work={worktyp}/>**
                <Foot year ={new Date().getFullYear()}/>
              </div>
            );
          }
      //index.js
          ReactDOM.render(
           <App />,
            document.getElementById('root')
          );
      

      【讨论】:

        【解决方案3】:

        在我的情况下,当我尝试将类型添加到 Promise.all 处理程序时会发生这种情况:

        Promise.all([1,2]).then(([num1, num2]: [number, number])=> console.log('res', num1));
        

        如果删除: [number, number],错误就消失了。

        【讨论】:

          【解决方案4】:

          这个错误主要是因为没有找到数组。只需检查您是否已映射到正确的数组。检查数组名称或声明。

          【讨论】:

          • 我在我定义的 arrayName 中缺少一个“s”。我真的浪费了 3 个小时!
          • @JoeKevinRayan 很高兴它有帮助!
          【解决方案5】:

          我考虑在taggon 的答案下对这个问题发表评论,但是,我觉得对那些对细节感兴趣的人来说,它应该得到更多的解释。

          Uncaught TypeError: Cannot read property 'value' of undefined 严格来说是 JavaScript 错误。
          (请注意,值可以是任何值,但对于这个问题,值是“地图”)

          理解这一点至关重要,这样可以避免无休止的调试循环。
          这个错误很常见,特别是如果刚开始使用 JavaScript(它是库/框架)。
          对于React,这与理解component lifecycle methods 有很大关系。

          // Follow this example to get the context
          // Ignore any complexity, focus on how 'props' are passed down to children
          
          import React, { useEffect } from 'react'
          
          // Main component
          const ShowList = () => {
            // Similar to componentDidMount and componentDidUpdate
            useEffect(() => {// dispatch call to fetch items, populate the redux-store})
          
            return <div><MyItems items={movies} /></div>
          }
          
          // other component
          const MyItems = props =>
            <ul>
              {props.items.map((item, i) => <li key={i}>item</li>)}
            </ul>
          
          
          /**
            The above code should work fine, except for one problem.
            When compiling <ShowList/>,
            React-DOM renders <MyItems> before useEffect (or componentDid...) is called.
            And since `items={movies}`, 'props.items' is 'undefined' at that point.
            Thus the error message 'Cannot read property map of undefined'
           */
          

          作为解决此问题的一种方法,@taggon 提供了解决方案(请参阅第一个答案或链接)。

          解决方案:设置一个初始/默认值。
          在我们的示例中,我们可以通过声明一个空数组的 default 值来避免 items 被“未定义”。

          为什么?这允许 React-DOM 最初渲染一个空列表。
          useEffectcomponentDid... 方法被执行时,组件会重新渲染填充的项目列表。

          // Let's update our 'other' component
          // destructure the `items` and initialize it as an array
          
          const MyItems = ({items = []}) =>
            <ul>
              {items.map((item, i) => <li key={i}>item</li>)}
            </ul>
          

          【讨论】:

            【解决方案6】:

            如果"this.props.data"有错误或者没有props.data数组,就会遇到错误"Cannot read property 'map' of undefined"

            更好的放置条件来检查数组,如

            if(this.props.data){
            this.props.data.map(........)
            .....
            }
            

            【讨论】:

              【解决方案7】:

              渲染前需要先放数据

              应该是这样的:

              var data = [
                {author: "Pete Hunt", text: "This is one comment"},
                {author: "Jordan Walke", text: "This is *another* comment"}
              ];
              
              React.render(
                <CommentBox data={data}/>,
                document.getElementById('content')
              );
              

              而不是这个:

              React.render(
                <CommentBox data={data}/>,
                document.getElementById('content')
              );
              
              var data = [
                {author: "Pete Hunt", text: "This is one comment"},
                {author: "Jordan Walke", text: "This is *another* comment"}
              ];
              

              【讨论】:

                【解决方案8】:

                我想你忘了改变

                data={this.props.data}
                

                data={this.state.data}
                

                在 CommentBox 的渲染函数中。当我按照教程进行操作时,我犯了同样的错误。因此整个渲染函数应该看起来像

                render: function() {
                  return (
                    <div className="commentBox">
                      <h1>Comments</h1>
                      <CommentList data={this.state.data} />
                      <CommentForm />
                    </div>
                  );
                }
                

                而不是

                render: function() {
                  return (
                    <div className="commentBox">
                      <h1>Comments</h1>
                      <CommentList data={this.props.data} />
                      <CommentForm />
                    </div>
                  );
                

                【讨论】:

                  【解决方案9】:

                  首先,设置更安全的初始数据:

                  getInitialState : function() {
                      return {data: {comments:[]}};
                  },
                  

                  并确保您的 ajax 数据。

                  如果您按照上述两个指令(如Demo.),它应该可以工作

                  更新:您可以只用条件语句包装 .map 块。

                  if (this.props.data) {
                    var commentNodes = this.props.data.map(function (comment){
                        return (
                          <div>
                            <h1>{comment.author}</h1>
                          </div>
                        );
                    });
                  }
                  

                  【讨论】:

                  • 这个解决方案有效,但我很好奇。如果我有一个更复杂的 JSON 结构,我是否必须以同样的方式初始化数据对象?似乎应该有更好的方法。谢谢
                  • @Nael 不,你不需要。只需像上面一样包装块。 :)
                  • 出现错误是因为this.props.data 为空。 .map 期望在一个数组上被调用。
                  • @timothyclifford 感谢您的回答。我了解this.props.data 为空,导致地图功能失败。但我不明白的是教程代码没有 if 子句。为什么教程中this.props.data不为空?
                  • this.props.data 由 AJAX 请求填充。 AJAX 是异步的,因此如果在填充数据之前渲染组件,this.props.data 将为空,您将收到错误消息。这有意义吗?
                  猜你喜欢
                  • 2021-12-10
                  • 2018-02-17
                  • 2020-05-27
                  • 2021-03-29
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-23
                  相关资源
                  最近更新 更多