سؤال

أواجه مشكلة في توصيل عناصر القائمة بمعالج الأحداث.إليك نموذجًا لواجهة المستخدم يُظهر تغيرات الحالة بمرور الوقت.إنها قائمة منسدلة (عبر Bootstrap)، مع عنصر القائمة الجذر الذي يعرض التحديد الحالي:

[ANN]<click  ...  [ANN]             ...    [BOB]<click  ...  [BOB]  
                    [Ann]                                      [Ann]
                    [Bob]<click + ajax                         [Bob]
                    [Cal]                                      [Cal]

الهدف النهائي هو تغيير محتوى الصفحة بشكل غير متزامن بناءً على اختيار المستخدم.النقر على بوب يجب أن يؤدي إلى تشغيل handleClick, ، لكنها ليست كذلك.

كملاحظة جانبية، أنا لست سعيدًا جدًا بالطريقة التي يتصل بها مكون DidMount this.handleClick();, ، ولكنه يعمل حاليًا كطريقة للحصول على محتوى القائمة الأولي من الخادم.

/** @jsx React.DOM */

var CurrentSelection = React.createClass({
  componentDidMount: function() {
    this.handleClick();
  },

  handleClick: function(event) {
    alert('clicked');
    // Ajax details ommitted since we never get here via onClick
  },
  getInitialState: function() {
    return {title: "Loading items...", items: []};
  },
  render: function() {
    var itemNodes = this.state.items.map(function (item) {
      return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
    });

    return <ul className='nav'>
      <li className='dropdown'>
        <a href='#' className='dropdown-toggle' data-toggle='dropdown'>{this.state.title}</a>
        <ul className='dropdown-menu'>{itemNodes}</ul>
      </li>
    </ul>;
  }
});


$(document).ready(function() {
  React.renderComponent(
    CurrentSelection(),
    document.getElementById('item-selection')
  );
});

أنا متأكد تقريبًا من أن فهمي الضبابي لنطاق جافا سكريبت هو السبب، لكن كل ما حاولته حتى الآن قد فشل (بما في ذلك محاولة تمرير المعالج عبر الدعائم).

هل كانت مفيدة؟

المحلول

المشكلة هي أنك تقوم بإنشاء عقد العنصر باستخدام وظيفة مجهولة، وداخل ذلك this يعني window.الإصلاح هو إضافة .bind(this) إلى الوظيفة المجهولة.

var itemNodes = this.state.items.map(function (item) {
  return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>;
}.bind(this));

أو إنشاء نسخة من this واستخدم ذلك بدلاً من ذلك:

var _this = this, itemNodes = this.state.items.map(function (item) {
  return <li key={item}><a href='#' onClick={_this.handleClick}>{item}</a></li>;
})

نصائح أخرى

كما أستطيع أن أفهم مواصفات المهمة لـ "Anna" و"Bob" و"Cal"، يمكن أن يكون الحل كما يلي (استنادًا إلى مكون التفاعل وES6):

العرض المباشر الأساسي موجود هنا

import React, { Component } from "react"

export default class CurrentSelection extends Component {
  constructor() {
    super()
    this.state = {
      index: 0
    }
    this.list = ["Anna", "Bob", "Cal"]
  }

  listLi = list => {
    return list.map((item, index) => (
      <li key={index}>
        <a
          name={item}
          href="#"
          onClick={e => this.onEvent(e, index)}
        >
          {item}
        </a>
      </li>
    ))
  }

  onEvent = (e, index) => {
    console.info("CurrentSelection->onEvent()", { [e.target.name]: index })
    this.setState({ index })
  }

  getCurrentSelection = () => {
    const { index } = this.state
    return this.list[index]
  }

  render() {
    return (
      <div>
        <ul>{this.listLi(this.list)}</ul>
        <div>{this.getCurrentSelection()}</div>
      </div>
    )
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top