জেএসের প্রতিক্রিয়া - আনকচড টাইপয়েরর: এই.পড়গুলি.ডেটা.ম্যাপ কোনও ফাংশন নয়


109

আমি রিএ্যাকটিজগুলির সাথে কাজ করছি এবং জেএসওএন ডেটা (ফাইল বা সার্ভার থেকে) প্রদর্শন করার চেষ্টা করার সময় এই ত্রুটিটি রোধ করতে পারি না:

Uncaught TypeError: this.props.data.map is not a function

আমি তাকিয়েছি:

কোড নিক্ষেপ করে প্রতিক্রিয়া জানায় "টাইপরর: এটি.প্রপস.ডাটা.ম্যাপ কোনও ফাংশন নয়"

React.js this.prop.data.map () কোনও ফাংশন নয়

এগুলির কোনওটিই আমাকে সমস্যার সমাধান করতে সহায়তা করে নি। আমার পৃষ্ঠাটি লোড হওয়ার পরে, আমি যাচাই করতে পারি যে এই.ডাটা.পড়গুলি অপরিজ্ঞাত নয় (এবং এর সাথে জেএসওএন অবজেক্টের সমান একটি মান রয়েছে - যার সাথে কল করতে পারে window.foo), সুতরাং মনে হয় এটি যখন লোকেটিং করা হয় তখন এটি লোড হয় না like ConversationList। আমি কীভাবে নিশ্চিত করব যে mapপদ্ধতিটি কোনও undefinedচলক নয়, JSON ডেটাতে কাজ করছে ?

var converter = new Showdown.converter();

var Conversation = React.createClass({
  render: function() {
    var rawMarkup = converter.makeHtml(this.props.children.toString());
    return (
      <div className="conversation panel panel-default">
        <div className="panel-heading">
          <h3 className="panel-title">
            {this.props.id}
            {this.props.last_message_snippet}
            {this.props.other_user_id}
          </h3>
        </div>
        <div className="panel-body">
          <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
        </div>
      </div>
    );
  }
});

var ConversationList = React.createClass({
  render: function() {

    window.foo            = this.props.data;
    var conversationNodes = this.props.data.map(function(conversation, index) {

      return (
        <Conversation id={conversation.id} key={index}>
          last_message_snippet={conversation.last_message_snippet}
          other_user_id={conversation.other_user_id}
        </Conversation>
      );
    });

    return (
      <div className="conversationList">
        {conversationNodes}
      </div>
    );
  }
});

var ConversationBox = React.createClass({
  loadConversationsFromServer: function() {
    return $.ajax({
      url: this.props.url,
      dataType: 'json',
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadConversationsFromServer();
    setInterval(this.loadConversationsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="conversationBox">
        <h1>Conversations</h1>
        <ConversationList data={this.state.data} />
      </div>
    );
  }
});

$(document).on("page:change", function() {
  var $content = $("#content");
  if ($content.length > 0) {
    React.render(
      <ConversationBox url="/conversations.json" pollInterval={20000} />,
      document.getElementById('content')
    );
  }
})

সম্পাদনা: নমুনা কথোপকথন.জসন যোগ করা

দ্রষ্টব্য - কলিং this.props.data.conversationsএকটি ত্রুটিও দেয়:

var conversationNodes = this.props.data.conversations.map...

নিম্নলিখিত ত্রুটি প্রদান করে:

আনকড টাইপ এরির: অপরিজ্ঞাতকৃত সম্পত্তি 'মানচিত্র' পড়তে পারে না

এখানে কথোপকথন.জসন:

{"user_has_unread_messages":false,"unread_messages_count":0,"conversations":[{"id":18768,"last_message_snippet":"Lorem ipsum","other_user_id":10193}]}

আমি উত্তর আপডেট করেছি। এছাড়াও, কিছু প্রস্তাবনাগুলি: প্রোপ টাইপগুলি যুক্ত করুন: {ডেটা: রিঅ্যাক্ট করুন ropপ্রপ টাইপস.আররে} ডেটা প্রকার যাচাই করতে কথোপকথনের তালিকায় এবং একটি উপাদান যোগ করুন ভিলউনমাউন্ট: এফএন () যে কথোপকথনবক্সের ব্যবধানকে "ক্লিয়ারইন্টারভাল" অন্তর্ভুক্ত করে।
ব্যবহারকারী120242

উত্তর:


134

.mapফাংশনটি কেবল অ্যারেতে উপলব্ধ।
দেখে মনে dataহচ্ছে আপনি যে ফর্ম্যাটটি প্রত্যাশা করছেন তা সেই রূপে নেই (এটি {} তবে আপনি প্রত্যাশা করছেন [])।

this.setState({data: data});

হতে হবে

this.setState({data: data.conversations});

কোন ধরণের "ডেটা" সেট করা হচ্ছে তা পরীক্ষা করে দেখুন এবং নিশ্চিত হন যে এটি অ্যারে is

কয়েকটি প্রস্তাবনা (প্রোপাইপ বৈধকরণ এবং ক্লিয়ারইন্টারভাল) সহ সংশোধিত কোড:

var converter = new Showdown.converter();

var Conversation = React.createClass({
  render: function() {
    var rawMarkup = converter.makeHtml(this.props.children.toString());
    return (
      <div className="conversation panel panel-default">
        <div className="panel-heading">
          <h3 className="panel-title">
            {this.props.id}
            {this.props.last_message_snippet}
            {this.props.other_user_id}
          </h3>
        </div>
        <div className="panel-body">
          <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
        </div>
      </div>
    );
  }
});

var ConversationList = React.createClass({
 // Make sure this.props.data is an array
  propTypes: {
    data: React.PropTypes.array.isRequired
  },
  render: function() {

    window.foo            = this.props.data;
    var conversationNodes = this.props.data.map(function(conversation, index) {

      return (
        <Conversation id={conversation.id} key={index}>
          last_message_snippet={conversation.last_message_snippet}
          other_user_id={conversation.other_user_id}
        </Conversation>
      );
    });

    return (
      <div className="conversationList">
        {conversationNodes}
      </div>
    );
  }
});

var ConversationBox = React.createClass({
  loadConversationsFromServer: function() {
    return $.ajax({
      url: this.props.url,
      dataType: 'json',
      success: function(data) {
        this.setState({data: data.conversations});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },

 /* Taken from 
    https://facebook.github.io/react/docs/reusable-components.html#mixins
    clears all intervals after component is unmounted
  */
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.map(clearInterval);
  },

  componentDidMount: function() {
    this.loadConversationsFromServer();
    this.setInterval(this.loadConversationsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="conversationBox">
        <h1>Conversations</h1>
        <ConversationList data={this.state.data} />
      </div>
    );
  }
});

$(document).on("page:change", function() {
  var $content = $("#content");
  if ($content.length > 0) {
    React.render(
      <ConversationBox url="/conversations.json" pollInterval={20000} />,
      document.getElementById('content')
    );
  }
})

32

আমার জন্য যা কাজ করেছিল তা হ'ল ব্যবহার করে প্রপস.ডেটাকে একটি অ্যারেতে রূপান্তর করা হয় data = Array.from(props.data); তবে আমি data.map()ফাংশনটি ব্যবহার করতে পারি


1
আমার টাইপটি ইতিমধ্যে একটি অ্যারে ছিল যেমন টাইপওফ সঠিক জিনিসটি দেখিয়েছিল দৈর্ঘ্যও সঠিক ছিল তবুও ত্রুটিটি উপস্থিত ছিল। এটি আমার জন্য এটি স্থির করে দিয়েছে। ধন্যবাদ!
ব্যবহারকারী 1829319

10

আরও সাধারণভাবে, আপনি নতুন ডেটাটিকে একটি অ্যারে রূপান্তর করতে এবং কনকটের মতো কিছু ব্যবহার করতে পারেন:

var newData = this.state.data.concat([data]);  
this.setState({data: newData})

এই প্যাটার্নটি আসলে ফেসবুকের টোডো ডেমো অ্যাপ্লিকেশনটিতে ("একটি অ্যাপ্লিকেশন" বিভাগটি দেখুন) https://facebook.github.io/react/ এ ব্যবহৃত হয়


1
এটি একটি ঝরঝরে টিপ / কৌশল, তবে আমি লক্ষ করতে চাই যে এটি আসল সমস্যাটি মুখোশ করবে এবং ওপি সমাধান করবে না। ওপির ক্ষেত্রে এটি কোনও উপকারে আসবে না, কারণ ডেটা এখনও ত্রুটিযুক্ত হবে (যা উদ্দেশ্য ছিল তা নয়)। কথোপকথনটি সম্ভবত খালি শেষ হবে কারণ সমস্ত প্রপসগুলি বাতিল হবে। আমি এই টিপটি ব্যবহার না করার পরামর্শ দেব, যদি না আপনি নিশ্চিত হন যে আপনার ডেটা আপনার পছন্দ মতো ফর্ম্যাটে রয়েছে, যাতে আপনি যখন অপ্রত্যাশিত আচরণ করবেন না তখন যখন ডেটা ফিরে আসবে আপনি যা ভাবেন সেটিকে তা নয়।
ব্যবহারকারী120242

1

এটি করার জন্য আপনার কোনও অ্যারের দরকার নেই।

var ItemNode = this.state.data.map(function(itemData) {
return (
   <ComponentName title={itemData.title} key={itemData.id} number={itemData.id}/>
 );
});

এটা কেমন আলাদা ভাই?
আমার পাঠক

1

এটি ঘটে কারণ অ্যাসিঙ্ক ডেটা আসার আগে উপাদানটি রেন্ডার হয়ে যায়, রেন্ডার করার আগে আপনার নিয়ন্ত্রণ করা উচিত।

আমি এটিকে সমাধান করেছি:

render() {
    let partners = this.props && this.props.partners.length > 0 ?
        this.props.partners.map(p=>
            <li className = "partners" key={p.id}>
                <img src={p.img} alt={p.name}/> {p.name} </li>
        ) : <span></span>;

    return (
        <div>
            <ul>{partners}</ul>
        </div>
    );
}
  • সম্পত্তিটি নাল / অপরিজ্ঞাতিত অবস্থায় মানচিত্রটি সমাধান করতে পারে না, তাই আমি প্রথমে একটি নিয়ন্ত্রণ করেছি

this.props && this.props.partners.length > 0 ?


0

mapফাংশনটি ব্যবহার করতে আপনাকে অবজেক্টটিকে একটি অ্যারেতে রূপান্তর করতে হবে :

const mad = Object.values(this.props.location.state);

this.props.location.stateঅন্য উপাদানতে পাস করা বস্তুটি কোথায় ।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.