【问题标题】:ReactJS - Communicating change in State between ComponentsReactJS - 在组件之间传达状态变化
【发布时间】:2015-06-10 22:44:58
【问题描述】:

我有以下组件:

由于我的按钮组件是通用的,它的事件也是通用的,我的无序列表也是如此;它是设置事件的下拉菜单。以下是两者的相关代码:

按钮组件:

render(){
  return(

    {/* whenClicked is a dropdown property  /*}
    <button onClick={this.props.whenClicked} type="button">
    .....
    </button>
    )

无序列表组件:

constructor(props) {
    super(props);
    this.state = {
        open:false
    }
}
render(){
    return(

         {/* toggle between show and hide  /*}
        <ul className={"dropdown-menu " + (this.state.open ? 'show' : '')}>
            {this.props.dropItems.map(function(item){
               ......
            })}
        </ul>
    )
}

由于按钮组件是通用的,它的点击事件取决于下拉组件的whenClicked属性。

下拉组件:

   'use strict'; 
   var React = require('react'),
       Button = require('./button'),
       UnorderedList = require('./unordered-list');

   class Dropdown extends React.Component{

   constructor(props) {
      super(props);
      this.state = {
          open:false
      }

     // added this as an update to my question per ssorallen
        this.handleClick = this.handleClick.bind(this)
   }

   handleClick(){
      this.setState({open : !this.state.open});
   }

  render(){

      return(
          <div className="dropdown">
              {/* whenClicked is a property not an event, per se. */}
              <Button whenClicked={this.handleClick}  />
              ......
             {/* // prop.items comes from app.jsx  */}
              <UnorderedList dropItems={this.props.items} />
          </div>
      )
  } }

   module.exports = Dropdown;

App.jsx:

 ....
       var selectItems = {
           title : "Choose a Fruit",
           items : [
               "Cantaloupe",
                .........
        ]
    }

    <Dropdown items={selectItems.items} multiSelect={true} title={selectItems.title} />
....

这张照片发生了什么:

  1. App.jsx 将水果项传递给 下拉组件

  2. 下拉列表依次将这些项目传递到无序列表

  3. 按钮组件连接到下拉列表的 whenClicked 属性。

  4. unorderlist 组件的初始状态 open 根据其属性设置为 false

      className={"dropdown-menu " + (this.state.open ? 'show' : '')}
    

所有这些都有效。

我的问题:

单击按钮时,下拉菜单的 whenClicked 事件会触发并切换打开状态

假设该事件会触发无序列表以在 true 和 false 之间切换其 打开状态,从而在其“下拉菜单”类中添加/删除 show

当 state.open 改变时,有人可以为我解释一下如何让下拉组件与无序列表通信吗?

我得到的错误是:

未捕获的类型错误:无法读取未定义的属性“setState”

【问题讨论】:

  • 如果他们解决了你的问题,你真的应该接受两个答案之一(我相信他们做到了)。就我个人而言,我认为 ssorallens 的回答最好地回答了您最初的问题。伙计们花时间回复,你欠他们那么多..!

标签: reactjs


【解决方案1】:

使用 ES6 类扩展 React.Component 时,成员方法不再像将对象传递给 React.createClass 时那样“自动绑定”。你可以bind them in the constructor来获取你习惯的行为:

class Dropdown extends React.Component {

  constructor() {
    ...
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    ...
    <div onClick={this.handleClick}>
    </div>
    ...
  }

}

【讨论】:

  • 好的,我在下拉列表的构造函数中添加了“this.handleClick = this.handleClick.bind(this)”,并且不再出现错误,但无序列表并没有改变它的打开状态。我不知道您的示例中的 div 元素是什么。
  • 我没有看到你的建议告诉我的无序列表在哪里切换它的打开状态。
【解决方案2】:

解决方案:

  1. 从 UnorderedList 类中完全删除了状态。
  2. 为下拉列表中的 UnorderedList 创建了带有状态值的 toggleState 道具,
  3. 将该属性传递给 UnorderedList 的“下拉菜单”类。

UnorderedList 类:

 'use strict';
 var React = require('react');

 class UnorderedList extends React.Component{

     constructor(props) {
         super(props);
     }
     render(){
         var listItemStyle = {
             cursor:'pointer'
         };

    return(
        <ul className={"dropdown-menu " + (this.props.toggleState ? 'show' : '')} role='menu' aria-labelledby='dropdownMenu1'>
            {this.props.dropItems.map(function(item){
                return (<li style={listItemStyle} key={item}><a>{item}</a></li>)
            })}
        </ul>
    )
} }

  module.exports = UnorderedList;

下拉类:

  'use strict';
  var React = require('react'),
      Button = require('./button'),
      UnorderedList = require('./unordered-list');

  class Dropdown extends React.Component{

      constructor(props) {
          super(props);
          this.state = {
              open:false
          }
          this.handleClick = this.handleClick.bind(this)
      }

handleClick(){
    this.setState({open : !this.state.open});
}

render(){
    return(
        <div className="dropdown">
            {/* whenClicked is a property not an event, per se. */}
            <Button whenClicked={this.handleClick} className="btn-warning" title={this.props.title} subTitleClassName="caret"></Button>
            <UnorderedList dropItems={this.props.items} toggleState={this.state.open} />
        </div>
    )
  }
 }
   module.exports = Dropdown;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-24
    • 2022-10-12
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多