Reactjs - 以正确的方式独立切换 class
Reactjs - toggling class indipendently with right way
我正在尝试添加 class 并删除它,它已经可用。我正在分别为每个元素做。但它总是指最后一个元素。正确的做法是什么?
有什么简单而优雅的方法可以做到这一点吗?
这是我的组件:
import React from "react";
import "./style.css";
export default class App extends React.Component {
divRef;
constructor(props){
super(props)
this.divRef = React.createRef();
}
toggleView = (e) => {
e.preventDefault();
if(this.divRef.current.classList.contains("active")){
this.divRef.current.classList.remove("active"); //always refer div 2!?
return;
}
this.divRef.current.classList.add("active");
}
render(){
return (
<div class="parent">
<div ref={this.divRef}>
1
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
<div ref={this.divRef}>2
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
</div>
);
}
}
也许你可以通过使用两个单独的 ref 来做到这一点,这里是演示:https://stackblitz.com/edit/react-b1wa4f?file=src%2FApp.js
我会利用 state
来实现这一点。不需要 refs
.
import React from "react";
import "./style.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
view1: false,
view2: false
};
}
toggleView = (e, view) => {
e.preventDefault();
this.setState({ [view]: !this.state[view] });
};
render() {
return (
<div class="parent">
<div className={this.state.view1 ? "active" : ""}>
1
<a href="#" onClick={e => this.toggleView(e, "view1")}>
toggle
</a>
</div>
<div className={this.state.view2 ? "active" : ""}>
2
<a href="#" onClick={e => this.toggleView(e, "view2")}>
toggle
</a>
</div>
</div>
);
}
}
编辑:
在这里,我展示了当我们有很多项目时这种方法如何扩展
import React from "react";
import "./style.css";
const NUM_ITEMS = 20;
const items = Array.from({ length: NUM_ITEMS }).map((_, idx) => ({
title: "title" + idx,
active: false
}));
const Item = ({ active, title, onToggle }) => (
<div className={active ? "active" : ""}>
{title}
<a
href="#"
onClick={e => {
e.preventDefault();
onToggle();
}}
>
toggle
</a>
</div>
);
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items
};
}
toggleView = idx => {
const items = [...this.state.items];
items[idx] = { ...items[idx], active: !items[idx].active };
this.setState({ items });
};
render() {
return (
<div class="parent">
{this.state.items.map((item, idx) => (
<Item
key={item.title}
active={item.active}
title={item.title}
onToggle={() => this.toggleView(idx)}
/>
))}
</div>
);
}
}
我明白了:
import React from "react";
import "./style.css";
export default class App extends React.Component {
divRef;
constructor(props){
super(props)
this.divRef = React.createRef();
}
toggleView = (e) => {
e.preventDefault();
const element = e.currentTarget.parentElement.classList;
if(element.contains("active")){
element.remove("active");
return;
}
element.add("active");
}
render(){
return (
<div class="parent">
<div ref={this.divRef}>
1
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
<div ref={this.divRef}>2
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
</div>
);
}
}
如果有人发现这种方法不对,请告诉我
我正在尝试添加 class 并删除它,它已经可用。我正在分别为每个元素做。但它总是指最后一个元素。正确的做法是什么?
有什么简单而优雅的方法可以做到这一点吗?
这是我的组件:
import React from "react";
import "./style.css";
export default class App extends React.Component {
divRef;
constructor(props){
super(props)
this.divRef = React.createRef();
}
toggleView = (e) => {
e.preventDefault();
if(this.divRef.current.classList.contains("active")){
this.divRef.current.classList.remove("active"); //always refer div 2!?
return;
}
this.divRef.current.classList.add("active");
}
render(){
return (
<div class="parent">
<div ref={this.divRef}>
1
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
<div ref={this.divRef}>2
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
</div>
);
}
}
也许你可以通过使用两个单独的 ref 来做到这一点,这里是演示:https://stackblitz.com/edit/react-b1wa4f?file=src%2FApp.js
我会利用 state
来实现这一点。不需要 refs
.
import React from "react";
import "./style.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
view1: false,
view2: false
};
}
toggleView = (e, view) => {
e.preventDefault();
this.setState({ [view]: !this.state[view] });
};
render() {
return (
<div class="parent">
<div className={this.state.view1 ? "active" : ""}>
1
<a href="#" onClick={e => this.toggleView(e, "view1")}>
toggle
</a>
</div>
<div className={this.state.view2 ? "active" : ""}>
2
<a href="#" onClick={e => this.toggleView(e, "view2")}>
toggle
</a>
</div>
</div>
);
}
}
编辑: 在这里,我展示了当我们有很多项目时这种方法如何扩展
import React from "react";
import "./style.css";
const NUM_ITEMS = 20;
const items = Array.from({ length: NUM_ITEMS }).map((_, idx) => ({
title: "title" + idx,
active: false
}));
const Item = ({ active, title, onToggle }) => (
<div className={active ? "active" : ""}>
{title}
<a
href="#"
onClick={e => {
e.preventDefault();
onToggle();
}}
>
toggle
</a>
</div>
);
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items
};
}
toggleView = idx => {
const items = [...this.state.items];
items[idx] = { ...items[idx], active: !items[idx].active };
this.setState({ items });
};
render() {
return (
<div class="parent">
{this.state.items.map((item, idx) => (
<Item
key={item.title}
active={item.active}
title={item.title}
onToggle={() => this.toggleView(idx)}
/>
))}
</div>
);
}
}
我明白了:
import React from "react";
import "./style.css";
export default class App extends React.Component {
divRef;
constructor(props){
super(props)
this.divRef = React.createRef();
}
toggleView = (e) => {
e.preventDefault();
const element = e.currentTarget.parentElement.classList;
if(element.contains("active")){
element.remove("active");
return;
}
element.add("active");
}
render(){
return (
<div class="parent">
<div ref={this.divRef}>
1
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
<div ref={this.divRef}>2
<a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
</div>
</div>
);
}
}
如果有人发现这种方法不对,请告诉我