React.js - 如何创建 Accordeon(与兄弟姐妹交谈)
React.js - how to create Accordeon (talking to siblings)
我刚开始使用 react.js,我喜欢组件的工作方式。我创建了一个 Card
组件,它会在点击时添加一个 css-class expanded
。这就像一个魅力。现在我希望所有其他卡片在单击另一张卡片后松开 expanded
属性。在 jQuery 中,我将使用 siblings
来执行此操作。
react.js 的正确解决方案是什么?
这是我的代码:
var Card = React.createClass({
getInitialState: function () {
return {
expanded: false,
//clickCount: 0
};
},
handleClick: function (event) {
this.setProps({expanded: !this.props.expanded});
},
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.state.expanded
});
return (
<li className={classes} onClick={this.handleClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
handleClick: function (event) {
console.log("clicked");
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card onClick={this.handleClick} name={pool.name} entf={pool.entf} />
);
});
return (<ul>
{pools}
</ul>
)
}
});
而不是使用 siblings
,您应该在 App
组件的 state
中保留扩展卡片的标识符,并在所选卡片发生变化时让 React 重新渲染。
这是一个如何使用 React 来实现的示例:
JSfiddle:http://jsfiddle.net/vdw27xpf/
var Card = React.createClass({
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.props.expanded
});
return (
<li className={classes} onClick={this.props.onClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
getInitialState : function(){
return { expandedCardName : null };
},
handleClick: function (value) {
this.setState({ expandedCardName : value });
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card key={pool.name}
expanded = { pool.name == this.state.expandedCardName }
onClick={this.handleClick.bind(this,pool.name)}
name={pool.name} entf={pool.entf} />
);
}.bind(this));
return (<ul>
{pools}
</ul>
)
}
});
var data = [ { name:"card1", entf:60 },{ name:"card2", entf:50 } ];
React.render(<App data={data} />, document.body);
React 是不是超级棒?
为了在不进行过多修改的情况下获得您想要的行为,我建议将回调 onClick
或 onExpand
传递给每个 <Card/>
。激活 Card 后,它会运行可以在 App 状态中设置变量(可能 activeCard
)的回调。在 App 的 render 方法中,修改 map 函数,为每张 Card 提供一个 expanded
布尔值,这取决于卡片的 name/id 是否匹配 activeCard
。在每张卡片的逻辑中使用新的 expanded
道具而不是 this.state.expanded
。
var Card = React.createClass({
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.props.expanded
});
return (
<li className={classes} onClick={this.props.onClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
getInitialState: function () {
return { activeCard: '' }
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card onClick={this.handleClick.bind(this,pool.name)} name={pool.name} entf={pool.entf} expanded={pool.name == this.state.activeCard} />
);
}.bind(this));
return (<ul>
{pools}
</ul>
)
},
handleClick: function (value) {
this.setState({ activeCard: value })
}
});
在 React 中工作时,请考虑如何使组件尽可能无状态。在像 jQuery 这样的范例中,这些部分通常会自行管理,但如果您想利用 React 的潜力,请始终留意如何 'trickle' 关闭状态。
我刚开始使用 react.js,我喜欢组件的工作方式。我创建了一个 Card
组件,它会在点击时添加一个 css-class expanded
。这就像一个魅力。现在我希望所有其他卡片在单击另一张卡片后松开 expanded
属性。在 jQuery 中,我将使用 siblings
来执行此操作。
react.js 的正确解决方案是什么?
这是我的代码:
var Card = React.createClass({
getInitialState: function () {
return {
expanded: false,
//clickCount: 0
};
},
handleClick: function (event) {
this.setProps({expanded: !this.props.expanded});
},
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.state.expanded
});
return (
<li className={classes} onClick={this.handleClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
handleClick: function (event) {
console.log("clicked");
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card onClick={this.handleClick} name={pool.name} entf={pool.entf} />
);
});
return (<ul>
{pools}
</ul>
)
}
});
而不是使用 siblings
,您应该在 App
组件的 state
中保留扩展卡片的标识符,并在所选卡片发生变化时让 React 重新渲染。
这是一个如何使用 React 来实现的示例:
JSfiddle:http://jsfiddle.net/vdw27xpf/
var Card = React.createClass({
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.props.expanded
});
return (
<li className={classes} onClick={this.props.onClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
getInitialState : function(){
return { expandedCardName : null };
},
handleClick: function (value) {
this.setState({ expandedCardName : value });
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card key={pool.name}
expanded = { pool.name == this.state.expandedCardName }
onClick={this.handleClick.bind(this,pool.name)}
name={pool.name} entf={pool.entf} />
);
}.bind(this));
return (<ul>
{pools}
</ul>
)
}
});
var data = [ { name:"card1", entf:60 },{ name:"card2", entf:50 } ];
React.render(<App data={data} />, document.body);
React 是不是超级棒?
为了在不进行过多修改的情况下获得您想要的行为,我建议将回调 onClick
或 onExpand
传递给每个 <Card/>
。激活 Card 后,它会运行可以在 App 状态中设置变量(可能 activeCard
)的回调。在 App 的 render 方法中,修改 map 函数,为每张 Card 提供一个 expanded
布尔值,这取决于卡片的 name/id 是否匹配 activeCard
。在每张卡片的逻辑中使用新的 expanded
道具而不是 this.state.expanded
。
var Card = React.createClass({
render: function () {
var cx = React.addons.classSet;
var classes = cx({
'card': true,
'expanded': this.props.expanded
});
return (
<li className={classes} onClick={this.props.onClick}>
<h1>{this.props.name}</h1>
<h2>{this.props.entf.toFixed(2)} km</h2>
</li>
)
}
});
var App = React.createClass({
getInitialState: function () {
return { activeCard: '' }
},
render: function () {
var pools = this.props.data.map(function (pool) {
return (
<Card onClick={this.handleClick.bind(this,pool.name)} name={pool.name} entf={pool.entf} expanded={pool.name == this.state.activeCard} />
);
}.bind(this));
return (<ul>
{pools}
</ul>
)
},
handleClick: function (value) {
this.setState({ activeCard: value })
}
});
在 React 中工作时,请考虑如何使组件尽可能无状态。在像 jQuery 这样的范例中,这些部分通常会自行管理,但如果您想利用 React 的潜力,请始终留意如何 'trickle' 关闭状态。