我正在尝试向数组中的对象添加onClick
事件处理程序,其中更改了单击对象的类,但它不是仅更改一个元素的类,而是更改所有类的类元素。
如何让函数一次仅处理一个section
元素?
class Tiles extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false,
content : []
};
this.onClicked = this.onClicked.bind(this);
componentDidMount() {
let url = '';
let request = new Request(url, {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json'
})
});
fetch(request)
.then(response => response.json())
.then(data => {
this.setState({
content : data
})
} );
}
onClicked() {
this.setState({
clicked: !this.state.clicked
});
}
render() {
let tileClass = 'tile-content';
if (this.state.clicked) {
tileClass = tileClass + ' active'
}
return (
<div className = 'main-content'>
{this.state.pages.map((item) =>
<section key = {item.id} className = {tileClass} onClick = {this.onClicked}>
<h4>{item.description}</h4>
</section>)}
<br />
</div>
)
}
class App extends React.Component {
render() {
return (
<div>
<Tiles />
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('content-app'))
答案 0 :(得分:0)
这种情况正在发生,因为一旦用户点击其中一个部分,您就会将活动类分配给所有部分。你需要以某种方式记住用户点击的位置。所以我建议你使用数组,你将存储所有点击部分的索引。在这种情况下,你的state.clicked现在是一个数组。
onClicked(number) {
let clicked = Object.assign([], this.state.clicked);
let index = clicked.indexOf(number);
if(index !== -1) clicked.splice(index, 1);
else clicked.push(number)
this.setState({
clicked: clicked
});
}
render() {
let tileClass = 'tile-content';
return (
<div className = 'main-content'>
{this.state.pages.map((item, i) => {
let tileClass = 'tile-content';
if(this.state.clicked.includes(i)) tile-content += ' active';
return (
<section key = {item.id} className = {tileClass} onClick = {this.onClicked.bind(this, i)}>
<h4>{item.description}</h4>
</section>
)
})}
<br />
</div>
)
}
答案 1 :(得分:0)
state.pages
需要跟踪单个点击状态,而不是实例范围内的点击状态
你的onClick处理程序应该接受一个索引,克隆state.pages
并拼接新的页面状态,过时的那个曾经是
您还可以在元素中添加data-index
,然后检查onClick (e) { e.currentTarget.dataset.index }
以了解哪个页面需要切换clickstate
答案 2 :(得分:0)
StackOverflow在评论中的代码工作特别糟糕,所以这里是使用setState的回调版本从@Taras Danylyuk实现onClicked以避免时间问题:
onClicked(number) {
this.setState((oldState) => {
let clicked = Object.assign([], this.state.clicked);
let index = clicked.indexOf(number);
if(index !== -1) {
clicked.splice(index, 1);
} else {
clicked.push(number);
}
return { clicked };
});
}
您需要这个的原因是因为您正在根据旧状态修改新状态。 React不保证您的状态是同步更新的,因此您需要使用回调函数来进行保证。
答案 3 :(得分:0)
你的'main-content'类中有onClicked()定义。这就是它发射的地方。
constructor(props) {
// super, etc., code
this.onClicked = this.onClicked.bind(this); // Remove this line.
}
删除该部分。
您可以将onClicked()
功能保持在原位。但是,您在render()中的调用不正确:onClick = {this.onClicked}>
。它访问onClicked ATTRIBUTE ,而不是onClicked FUNCTION ,它应该是this.onClicked()。
让我在render()
稍微清理你的电话:
render() {
let tileClass = 'tile-content';
return (
<div className = 'main-content'>
// some stuff
<section
key={item.id}
className={tileClass}
onClick={() => this.onClicked()} // Don't call bind here.
>
<h4>{item.description}</h4>
</section>
// some other stuff
</div>
)
}