ارتباط بین دو کامپوننت در React

اپلیکیشن من شامل یک لیست با فیلتر های آن و یک button برای تغییر layout می باشد. در حال حاضر از سه کامپوننت:

  • </list>
  • </Filters>
  • </TopBar>

استفاده می کنم. می خوام زمانی که تنظیمات در </Filters> تغییر کرد متدی در کامپوننت </list> برای بروزرسانی view اجرا شود.

چطور میتونم بین این سه کامپوننت ارتباط برقرار کنم؟ آیا باید از مدل داده global برای انجام این کار استفاده کنم؟ 

0
مسعود پرسیده شده در ۲۳ اسفند ۱۳۹۷
16 سوال
0 پاسخ
4امتیاز
Share in:
1 پاسخ

بهترین روش بستگی به برنامه ریزی شما برای این کامپوننت ها دارد. من دو سناریو زیر را در نظر می گیرم:

  1. <Filters />  فرزند کامپوننت <List />  است.
  2. هر دو کامپوننت <Filters /> و <List />  فرزندان یک کامپوننت والد هستند.

سناریو 1:

در این سناریو شما باید یک متد اداره کننده را از </List> به </Filters> بفرستید که می تواند در رویداد onChange برای فیلتر کردن با مقدار جاری فراخوانی شود.

از این لینک می توانید نمونه کد سناریو 1 را مشاهده کنید.

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    var content;
    if (displayedItems.length > 0) {
      var items = displayedItems.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

React.renderComponent(<List />, document.body);

سناریو 2:

مثل سناریو 1 یک تابع اداره کننده را باید در نظر بگیریم، با این تفاوت که یک کامپوننت والد برای هر دو ایجاد می کنیم و تابع اداره کننده را به کامپوننت </Filters> و لیست فیلتر شده را برای کامپوننت </List> ارسال می کنیم. این روش دو کامپوننت </List> و </Filter> را از هم جدا می کند و راه بهتری به نظر می رسد.

از این لینک می توانید نمونه کد سناریو 2 را مشاهده کنید.

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  render: function() {
    var content;
    if (this.props.items.length > 0) {
      var items = this.props.items.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }
    return (
      <div className="results">
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

var ListContainer = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <List items={displayedItems} />
      </div>
    );
  }
});

React.renderComponent(<ListContainer />, document.body);

 

1
دانیال
پاسخ داده در ۲۶ اسفند ۱۳۹۷
0 سوال
50 پاسخ
27امتیاز
پاسخ شماپاسخ شما با موفقیت ثبت شد.پاسخی وارد نشده است.

ارسال پاسخ