【问题标题】:ReactJs: Maintain seperate state for Tabs having same componentReactJs:为具有相同组件的标签维护单独的状态
【发布时间】:2017-06-13 05:46:01
【问题描述】:

我在一个组件中使用选项卡结构,两个选项卡内部都有相同的组件。

如果单击添加按钮,则会将一个新组件添加到选项卡中,现在如果我切换选项卡并转到选项卡 2,其中也有相同的组件。

我试图在下面的小提琴中复制场景。

https://jsfiddle.net/rzv6Lrjh/89/

var App = React.createClass({
  render: function () {
    return (
      <div>
        <Tabs selected={0}>
          <Pane label="Tab 1">
            <Tickets/>
          </Pane>
          <Pane label="Tab 2">
            <Tickets/>
          </Pane>
        </Tabs>
      </div>
    );
  }
});

【问题讨论】:

  • 不确定您想要什么,但我认为您应该考虑将“ticketlist”作为门票组件的属性发送,并在顶级组件级别状态下维护 2 个不同的列表
  • @AshKander 你能看看我添加的小提琴吗,问题是两个选项卡都有相同的组件,所以如果我在选项卡 1 中对组件进行一些更改,同样会在选项卡 2 中反映出来。

标签: reactjs state


【解决方案1】:

好的,所以您只需要让 react 了解您的 2 个门票组件是不同的。

你可以简单地通过向这个组件添加一个虚拟属性来实现这一点

<Tickets key="1/>

对于第一个标签和

<Tickets key="2/>

第二个。然后你会得到你期望的 2 次渲染 ;)


将票作为道具传递的完整答案

var Tabs = React.createClass({
    displayName: 'Tabs',
    propTypes: {
    selected: React.PropTypes.number,
    children: React.PropTypes.oneOfType([
      React.PropTypes.array,
      React.PropTypes.element
    ]).isRequired
  },
  getDefaultProps: function () {
    return {
        selected: 0
    };
  },
  getInitialState: function () {
    return {
        selected: this.props.selected
    };
  },
  shouldComponentUpdate(nextProps, nextState) {
    return this.props !== nextProps || this.state !== nextState;
  },
  handleClick: function (index, event) {
    event.preventDefault();
    this.setState({
        selected: index
    });
  },
  _renderTitles: function () {
    function labels(child, index) {
        var activeClass = (this.state.selected === index ? 'active' : '');
        return (
        <li key={index}>
            <a href="#" 
            className={activeClass}
            onClick={this.handleClick.bind(this, index)}>
            {child.props.label}
          </a>
        </li>
      );
    }
    return (
        <ul className="tabs__labels">
        {this.props.children.map(labels.bind(this))}
      </ul>
    );
  },
  _renderContent: function () {
    return (
        <div className="tabs__content">
            {this.props.children[this.state.selected]}
      </div>
    );
  },
    render: function () {
    return (
        <div className="tabs">
        {this._renderTitles()}
        {this._renderContent()}
      </div>
    );
  }
});

var Pane = React.createClass({
    displayName: 'Pane',
  propTypes: {
    label: React.PropTypes.string.isRequired,
    children: React.PropTypes.element.isRequired
  },
    render: function () {
    return (
        <div>
        {this.props.children}
      </div>
    );
  }
});

var CreateTicket = React.createClass({
  getInitialState: function() {
    return{};
  },
  render: function() {
    return(
      <button type="button" onClick={this.props.createTicket} className="add-another-ticket">
        +Add Ticket
      </button>
    );
  }
});

var Tickets = React.createClass({
  render: function() {
    return (
      <div>
        {this.props.tickets}
        <CreateTicket createTicket={this.props.onCreateTicket} />
      </div>
    );
  }
});

var IndividualTicketInput = React.createClass({
  getInitialState: function() {
    return { ticket: {name: '', quantity: '', price: null} };
  },
  render: function() {
    return (
      <ul>
        <li>
          <label>Ticket Name</label>
          <input className="ticket-name" type="text" placeholder="E.g. General Admission" value={this.state.ticket.name} />
        </li>
        <li>
          <label>Quantity Available</label>
          <input className="quantity" type="number" placeholder="100" value={this.state.ticket.quantity} />
        </li>
          <li>
            <label>Price</label>
            <input className="price" type="number" placeholder="25.00" value={this.state.ticket.price} />
          </li>
        <li>
          <button type="button" className="delete-ticket" onClick={this.deleteTicket}><i className="fa fa-trash-o delete-ticket"></i></button>
        </li>
      </ul>
    );
  }
});

var App = React.createClass({
    getInitialState: function() {
        return {
            tickets1: [(<IndividualTicketInput/>)],
            tickets2: [(<IndividualTicketInput/>)]
        }
    },
    onCreateTicket1: function() {
        this.state.tickets1.push(<IndividualTicketInput/>);
    },
    onCreateTicket2: function() {
        this.state.tickets2.push(<IndividualTicketInput/>);
    },
    render: function() {
        return (
        <div>
            <Tabs selected={0}>
                <Pane label="Tab 1">
                    <Tickets tickets={this.state.tickets1} onCreateTicket={this.onCreateTicket1.bind(this)}/>
                </Pane>
                <Pane label="Tab 2">
                    <Tickets tickets={this.state.tickets2} onCreateTicket={this.onCreateTicket2.bind(this)}/>
                </Pane>
            </Tabs>
        </div>
        );
    }
});

ReactDOM.render(<App />, document.querySelector('.container'));

【讨论】:

  • 感谢它的工作。一个小问题,jsfiddle.net/rzv6Lrjh/90。如果我在选项卡 1 中单击添加并转到选项卡 2,它工作正常,但是当我从选项卡 2 切换到选项卡 1 时,它的状态与选项卡 2
猜你喜欢
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2016-12-29
  • 2021-07-19
  • 2021-07-03
  • 2014-11-23
相关资源
最近更新 更多