将onClick值存储到数组并进一步通信

时间:2016-08-05 09:30:00

标签: javascript arrays reactjs

我正在构建一个具有过滤功能的React应用程序,但这不是问题所在,我想在直接处理过滤之前我必须按照自己的方式进行操作。我已经看了https://facebook.github.io/react/tips/expose-component-functions.html并使用了我对它的理解,但现在我不再确定错误或从何处开始。

我有一个FilterContainer(父)组件,它呈现Filter(子)组件。每个过滤器组件都是一个过滤器列表,这使得我必须在父项而不是子项中执行此功能,因为过滤器是彼此独立的。

当用户点击其中一个过滤器时,我想将点击的元素的值存储到数组中,然后使用该数组过滤掉应该显示的公寓。我的Javascript知识有限,所以我似乎无法自己解决这个问题。

现在,当我点击其中一个Filter按钮时,没有任何反应,并且console.log没有输出任何有意义的内容。

This is what it looks like on the app

这是过滤器(子)组件



var Filter = React.createClass({
  getDefaultProps() {
    return {
      filterList: [],
      name: '',
      id: '',
      props: []
    };
  },
  render() {
    
    return (
      <div id={this.props.id} className="filterCloud quarter-section">
        <h3>{this.props.name}</h3>
        <ul>
          {this.props.filterList.map(function(listValue, i) {
            return <li onClick={this.props.onClick} key={i}> {listValue} </li>;
          }.bind(this))}
        </ul>
      </div>
    )
  }
});
&#13;
&#13;
&#13;

这是FilterContainer(父)组件

&#13;
&#13;
const FilterContainer = React.createClass({
  getInitialState() {
    return {
      selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
    };
  },
  handleClick(i) {
    this.setState({ clicked: i });
    var index = this.state.selected.indexOf(i);
    if (index === -1) {
      this.state.selected.push(i);
    } else {
      this.state.selected.splice(index, 1);
    }
    console.log(this.state);
  },
  render () {
    var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
    var boundClick = this.handleClick;
    return (
      <section id="filterContainer" className="container">
        <Filter
          onClick={boundClick}
          id="kvartFilter"
          name={'Kvart'}
          filterList={[
            'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
        ]} />
        <Filter
          onClick={boundClick}
          id="cijenaFilter"
          name={'Cijena'}
          filterList={[
            '< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
        ]} />
        <Filter
          onClick={boundClick}
          id="osobeFilter"
          name={'Broj osoba'}
          filterList={[
            '1', '2', '3', '4', '5', '6'
        ]} />
        <Filter
          onClick={boundClick}
          id="kvadraturaFilter"
          name={'Kvadratura'}
          filterList={[
            '40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
        ]} />
      </section>
    )
  }
});
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

在@ oliv37的帮助下,我正在回答我自己的问题以供将来参考。

所做的更改:

  • 删除了var boundClick = this.handleClick;
  • 将过滤器组件中的onClick={boundClick}编辑为onClick={this.handleClick}
  • 删除了this.setState({ clicked: i });,是多余的
  • 将过滤器组件中的onClick输出更改为return <li onClick = {() => {this.props.onClick(listValue)}} key={i}> {listValue} </li>;

以下是更新的组件

过滤组件

var Filter = React.createClass({
  getDefaultProps() {
    return {
      filterList: [],
      name: '',
      id: '',
      props: []
    };
  },
  render() {

    return (
      <div id={this.props.id} className="filterCloud quarter-section">
        <h3>{this.props.name}</h3>
        <ul>
          {this.props.filterList.map(function(listValue, i) {
            return <li onClick = {() => {this.props.onClick(listValue)}} key={i}> {listValue} </li>;
          }.bind(this))}
        </ul>
      </div>
    )
  }
});

FilterContainer组件

const FilterContainer = React.createClass({
  getInitialState() {
    return {
      selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
    };
  },
  handleClick(filterValue) {
    var index = this.state.selected.indexOf(filterValue);
    if (index === -1) {
      this.state.selected.push(filterValue);
    } else {
      this.state.selected.splice(index, filterValue);
    }
    console.log(this.state);
  },
  render () {
    var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
    return (
      <section id="filterContainer" className="container">
        <Filter
          onClick={this.handleClick}
          id="kvartFilter"
          name={'Kvart'}
          filterList={[
            'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="cijenaFilter"
          name={'Cijena'}
          filterList={[
            '< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="osobeFilter"
          name={'Broj osoba'}
          filterList={[
            '1', '2', '3', '4', '5', '6'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="kvadraturaFilter"
          name={'Kvadratura'}
          filterList={[
            '40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
        ]} />
      </section>
    )
  }
});

答案 1 :(得分:0)

这里有很多话要说。

首先,设置clicked状态属性,但之前没有定义它,也没有在之后使用它。

其次,您通过直接在handleClick上调用slicepush来直接改变state方法中的状态。

第三,setState()是异步的,不要指望立即应用更改(console.log语句不会显示您所期望的内容。)

请看下面的工作片段:

const FilterContainer = React.createClass({
  getInitialState() {
    return {
      selected: [] /* Holds the filters the user clicked, needs to get updated every time a filter is interacted with */
    };
  },
  handleClick(name) {
    var index = this.state.selected.indexOf(name);
    this.setState(function(state) {
      var selected = index === -1 ? (
        state.selected.concat([name])
      ) : (
        state.selected.filter(function(filter, i) { return index !== i })
      );
      return {
        selected: selected
      }
    });
  },
  render () {
    console.log(this.state);
    var filters = []; {/* Doesnt filter any apartments to display them on initial load */}
    return (
      <section id="filterContainer" className="container">
        <Filter
          onClick={this.handleClick}
          id="kvartFilter"
          name={'Kvart'}
          filterList={[
            'Šubićevac', 'Meterize', 'Baldekin', 'Vidici', 'Rokići', 'Grad'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="cijenaFilter"
          name={'Cijena'}
          filterList={[
            '< 600kn', '600kn - 700kn', '700kn - 800kn', '800kn - 900kn', '> 900kn'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="osobeFilter"
          name={'Broj osoba'}
          filterList={[
            '1', '2', '3', '4', '5', '6'
        ]} />
        <Filter
          onClick={this.handleClick}
          id="kvadraturaFilter"
          name={'Kvadratura'}
          filterList={[
            '40m - 60m', '60m - 70m', '70m - 80m', '> 80m'
        ]} />
      </section>
    )
  }
});

var Filter = React.createClass({
  getDefaultProps() {
    return {
      filterList: [],
      name: '',
      id: '',
      props: []
    };
  },
  render() {
    
    return (
      <div id={this.props.id} className="filterCloud quarter-section">
        <h3>{this.props.name}</h3>
        <ul>
          {this.props.filterList.map(function(listValue, i) {
            return <li onClick={() => this.props.onClick(listValue)} key={i}> {listValue} </li>;
          }.bind(this))}
        </ul>
      </div>
    )
  }
});

ReactDOM.render(<FilterContainer/>,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

BONUS:您不应该将索引用作key,因为如果您更改了可能的过滤器数量(可能通过某种方面搜索),那么反应将会遇到这些键并且无法协调某些DOM元素正确,最终难以找到错误。