2016-03-04 52 views
1

我试图让我的组件保持纯粹(状态生活在正在改变的组件外) - 通过从父进程传入状态。React.js - 处理哑孩子状态的模式?

我有三个链接,我想要更改为活动,但不是影响所有他们,我只想影响被点击/活动的。

有些问题没有答案:逻辑应该在哪里筛选出哪个元素被点击?我们如何通过让孩子哑巴来做到这一点?

这里是我走到这一步:

的jsfiddle - https://jsfiddle.net/69z2wepo/33470/

var SomeElement = React.createClass({ 
    render: function() { 
    return(
     <a className={this.props.className} onClick={this.props.onClick} href="#">Click Me!</a> 
    ) 
    } 
}); 

var App = React.createClass({ 
    click: function(e) { 
    this.setState({class: "active"}) 
    }, 
    getInitialState: function() { 
    return({class: ""}) 
    }, 
    render: function() { 
    return(
     <div> 
     <SomeElement className={this.state.class} onClick={this.click} /> 
     <SomeElement className={this.state.class} onClick={this.click} /> 
     <SomeElement className={this.state.class} onClick={this.click} /> 
     </div> 
    ) 
    } 
}); 

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

在此先感谢。

回答

2

首先,元素处于活动状态时使用的类的名称应该在元素内部。父组件不应该知道的是:

var SomeElement = React.createClass({ 
    className: function() { 
    return this.props.active ? "active" : ""; 
    }, 
    render: function() { 
    return (  
     <a className={this.className()} onClick={this.props.onClick} href="#">Click Me!</a> 
    ) 
    } 
}); 

<SomeElement active={true,false} onClick={this.click} /> 

下一个点取决于你要如何表示你的应用程序的状态。我举两个例子:

state: { 
    element1Active: false, 
    element2Active: false, 
    element3Active: false, 
} 

click: function(elementNumber) { 
    var stateUpdate = {}, key = 'element' + elementNumber + 'Active'; 
    stateUpdate[key] = !this.state[key]; 
    this.setState(stateUpdate); 
} 

<SomeElement active={this.state.element1Active} onClick={this.click} /> 

或(可能更好)

state: { 
    activeElementIndex: 0, 
} 

click: function(elementIndex) { 
    this.setState({activeElementIndex: elementIndex}); 
} 

<SomeElement active={this.state.activeElementIndex === 0} onClick={this.click} /> 

最后,过滤被点击的按钮,你可以绑定参数回调:

return(
    <SomeElement active={this.state.activeElementIndex === 0} onClick={this.click.bind(this, 0)} /> 
    <SomeElement active={this.state.activeElementIndex === 1} onClick={this.click.bind(this, 1)} /> 
    <SomeElement active={this.state.activeElementIndex === 2} onClick={this.click.bind(this, 2)} /> 
) 
+0

看起来不错,我喜欢你的解决方案 - 只是想指出'SomeElement'里面的变量是无效的代码 - 因为这是一个对象而不是一个有趣的它应该是这样的功能: '''className:function(){ \t return this.props.active? “主动”:“不主动”; },'''并用作'this.className()' – AntonB