我有以下内容:
var Tab = React.createClass({
getInitialState: function(){
return {
selected:''
}
},
activateTab: function(e) {
e.preventDefault();
$('.navigation--active').removeClass('navigation--active');
this.setState({selected : true});
},
render: function() {
var isActive = this.state.selected === true ? 'navigation--active': '';
return (
<li onClick={this.activateTab} className={isActive}>
<p>
{this.props.content}
</p>
</li>
);
}
});
var Tabs = React.createClass({
render: function() {
var tabs = [],
total = this.props.data.points.total,
handleClick = this.handleClick;
total.forEach(function(el, i){
tabs.push(
<Tab content = {el.name}
key = {i}/>
);
});
return (
<ul className="navigation">
{tabs}
</ul>
);
}
});
然而,只有当你在每个标签上点击一次时它才有效,如果你在同一个标签上第二次点击该课程就不再添加了
答案 0 :(得分:16)
在这种情况下,最好将状态管理移动到父组件Tabs
,并将仅需要检测类名称或在父项中设置新状态的子项传递给子项
var Tab = React.createClass({
render: function() {
return <li
className={ this.props.isActive ? 'navigation--active': '' }
onClick={ this.props.onActiveTab }
>
<p>{ this.props.content }</p>
</li>
}
});
var Tabs = React.createClass({
getInitialState: function() {
return { selectedTabId: 1 }
},
isActive: function (id) {
return this.state.selectedTabId === id;
},
setActiveTab: function (selectedTabId) {
this.setState({ selectedTabId });
},
render: function() {
var total = this.props.data.points.total,
tabs = total.map(function (el, i) {
return <Tab
key={ i }
content={ el.name }
isActive={ this.isActive(el.id) }
onActiveTab={ this.setActiveTab.bind(this, el.id) }
/>
}, this);
return <ul className="navigation">
{ tabs }
</ul>
}
});
const data = {
points: {
total: [
{ id: 1, name: 'tab-1', text: 'text' },
{ id: 2, name: 'tab-2', text: 'text-2' },
{ id: 3, name: 'tab-3', text: 'text-2' }
]
}
}
ReactDOM.render(
<Tabs data={ data } />,
document.getElementById('container')
);
.navigation {}
.navigation--active {
color: red;
}
<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="container"></div>
答案 1 :(得分:0)
Necro海报在这里。 上面的答案很酷!
无论如何,这是带有recompose
和styled-components
的2018年升级答案。您甚至可以使用它来创建HOC,以获得令人愉快的可重用性!
https://codesandbox.io/s/1826454zl7
import React from "react";
import ReactDOM from "react-dom";
import { compose, withState, withHandlers } from "recompose";
import styled from "styled-components";
const enchancer = compose(
withState("selectedTabId", "setSelectedTabId", 1),
withHandlers({
isActive: props => id => {
return props.selectedTabId === id;
},
setActiveTab: props => id => {
props.setSelectedTabId(id);
}
})
);
const Tabs = enchancer(props => {
return (
<ul>
{props.data.map((el, i) => {
return (
<Tab
key={i}
content={el.name}
isActive={props.isActive(el.id)}
onActiveTab={() => props.setActiveTab(el.id)}
/>
);
})}
</ul>
);
});
const Tab = props => {
return (
<StyledLi isActive={props.isActive} onClick={props.onActiveTab}>
<p>{props.content}</p>
</StyledLi>
);
};
const StyledLi = styled.li`
font-weight: ${({ isActive }) => (isActive ? 600 : 100)};
cursor: pointer;
font-family: Helvetica;
transition: 200ms all linear;
`;
const data = [
{ id: 1, name: "tab-1", text: "text" },
{ id: 2, name: "tab-2", text: "text-2" },
{ id: 3, name: "tab-3", text: "text-2" }
];
const ExampleApp = () => <Tabs data={data} />;
ReactDOM.render(<ExampleApp />, document.getElementById("app"));
基本思想是,您需要获取选定的索引,在每次单击时映射该项目,将选定的索引与所有其他索引进行比较,如果找到匹配项,则对需要的组件的prop返回true。