React - 仅在单击项目时添加 class
React - Add a class only when an item is clicked
我有一个这样的无状态组件:
import React from 'react';
import PropTypes from 'prop-types';
const Panel = (props) => {
return(
<div
className={props.className}
onClick={props.onClick}>
<p>{props.firstChild}</p>
<p>{props.secondChild}</p>
<p>{props.thirdChild}</p>
</div>
)
}
Panel.propTypes = {
onClick: PropTypes.func.isRequired,
className:PropTypes.any.isRequired,
firstChild: PropTypes.string.isRequired,
secondChild: PropTypes.string.isRequired,
thirdChild: PropTypes.string.isRequired,
};
export default Panel
我的 Class 组件是这样的:
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
open: false,
}
}
toggleOpen = () => {
console.log('hi')
this.setState({
open: !this.state.open
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={this.toggleOpen}
className={this.state.open ? "panel panel1 open open-active " : "panel panel1"}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={this.toggleOpen}
className={this.state.open ? "panel panel2 open open-active " : "panel panel2"}
/>
</div>
)
};
}
export default ImageGallery;
onClick 一个 Panel
组件希望这个组件将 open
和 open-active
类 添加到我的项目中。
目前一个项目上的 onClock 都打开了,但我希望两者分开处理。
我不确定如何以最干净的方式使用状态和 类。
感谢您的帮助
您需要单独的值来跟踪这些面板,如下所示。我没有测试代码,但应该是这样的。
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
panel1: {
open: false
},
panel2: {
open: false
}
}
}
toggleOpen = (key) => {
console.log('hi')
this.setState({
[key]: {
open: !this.state[key].open
}
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen('panel1')}
className={this.state.open ? "panel panel1 open open-active " : "panel panel1"}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen('panel2')}
className={this.state.open ? "panel panel2 open open-active " : "panel panel2"}
/>
</div>
)
};
}
export default ImageGallery;
另外,为了便于管理类名,建议使用classnames包。
为每个 <Panel />
组件添加一个名称:
<Panel
name="Foo"
isOpen={this.state.fooOpen}
...
/>
<Panel
name="Bar"
isOpen={this.state.barOpen}
...
/>
在您的处理程序中使用如下代码:
toggleOpen = event => {
if(event.target.name === "Foo") {
this.setState({fooOpen: true})
} else {
this.setState({barOpen: true})
}
}
确保在您的 Panel 组件中将名称向下传递给您从中调用处理程序的元素。
有趣的是,我今天早上刚刚在我的应用程序中编写了与此非常相似的代码。
我是这样做的(如果您一次只想打开一个面板):您可以在此处的沙箱中看到它的工作原理。 https://codesandbox.io/s/mow9nyj958
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
openPanel: undefined,
}
}
toggleOpen = (panelNumber) => {
console.log('hi')
this.setState(prevState => ({
openPanel: (prevState.openPanel === panelNumber) ? undefined : panelNumber
}))
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen(1)}
className={`panel panel1 ${(this.state.openPanel === 1) ? "open open-active" : ""}`}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen(2)}
className={`panel panel1 ${(this.state.openPanel === 2) ? "open open-active" : ""}`}
/>
</div>
)
};
}
export default ImageGallery;
但我假设您希望能够同时打开两个面板,因此您可以执行类似的操作。
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
panel1Open: false,
panel2Open: false
}
}
toggleOpen = (panelNumber) => {
console.log('hi')
this.setState(prevState => {
const key = `panel${panelNumber}Open`;
return { [key]: !prevState[key] }
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen(1)}
className={`panel panel1 ${this.state.panel1Open ? "open open-active" : ""}`}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen(2)}
className={`panel panel1 ${this.state.panel2Open ? "open open-active" : ""}`}
/>
</div>
)
};
}
我有一个这样的无状态组件:
import React from 'react';
import PropTypes from 'prop-types';
const Panel = (props) => {
return(
<div
className={props.className}
onClick={props.onClick}>
<p>{props.firstChild}</p>
<p>{props.secondChild}</p>
<p>{props.thirdChild}</p>
</div>
)
}
Panel.propTypes = {
onClick: PropTypes.func.isRequired,
className:PropTypes.any.isRequired,
firstChild: PropTypes.string.isRequired,
secondChild: PropTypes.string.isRequired,
thirdChild: PropTypes.string.isRequired,
};
export default Panel
我的 Class 组件是这样的:
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
open: false,
}
}
toggleOpen = () => {
console.log('hi')
this.setState({
open: !this.state.open
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={this.toggleOpen}
className={this.state.open ? "panel panel1 open open-active " : "panel panel1"}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={this.toggleOpen}
className={this.state.open ? "panel panel2 open open-active " : "panel panel2"}
/>
</div>
)
};
}
export default ImageGallery;
onClick 一个 Panel
组件希望这个组件将 open
和 open-active
类 添加到我的项目中。
目前一个项目上的 onClock 都打开了,但我希望两者分开处理。
我不确定如何以最干净的方式使用状态和 类。
感谢您的帮助
您需要单独的值来跟踪这些面板,如下所示。我没有测试代码,但应该是这样的。
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
panel1: {
open: false
},
panel2: {
open: false
}
}
}
toggleOpen = (key) => {
console.log('hi')
this.setState({
[key]: {
open: !this.state[key].open
}
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen('panel1')}
className={this.state.open ? "panel panel1 open open-active " : "panel panel1"}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen('panel2')}
className={this.state.open ? "panel panel2 open open-active " : "panel panel2"}
/>
</div>
)
};
}
export default ImageGallery;
另外,为了便于管理类名,建议使用classnames包。
为每个 <Panel />
组件添加一个名称:
<Panel
name="Foo"
isOpen={this.state.fooOpen}
...
/>
<Panel
name="Bar"
isOpen={this.state.barOpen}
...
/>
在您的处理程序中使用如下代码:
toggleOpen = event => {
if(event.target.name === "Foo") {
this.setState({fooOpen: true})
} else {
this.setState({barOpen: true})
}
}
确保在您的 Panel 组件中将名称向下传递给您从中调用处理程序的元素。
有趣的是,我今天早上刚刚在我的应用程序中编写了与此非常相似的代码。
我是这样做的(如果您一次只想打开一个面板):您可以在此处的沙箱中看到它的工作原理。 https://codesandbox.io/s/mow9nyj958
import React, { Component } from 'react';
import Panel from './panel'
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
openPanel: undefined,
}
}
toggleOpen = (panelNumber) => {
console.log('hi')
this.setState(prevState => ({
openPanel: (prevState.openPanel === panelNumber) ? undefined : panelNumber
}))
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen(1)}
className={`panel panel1 ${(this.state.openPanel === 1) ? "open open-active" : ""}`}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen(2)}
className={`panel panel1 ${(this.state.openPanel === 2) ? "open open-active" : ""}`}
/>
</div>
)
};
}
export default ImageGallery;
但我假设您希望能够同时打开两个面板,因此您可以执行类似的操作。
class ImageGallery extends Component {
constructor(props){
super(props)
this.state = {
panel1Open: false,
panel2Open: false
}
}
toggleOpen = (panelNumber) => {
console.log('hi')
this.setState(prevState => {
const key = `panel${panelNumber}Open`;
return { [key]: !prevState[key] }
})
}
render() {
return (
<div className="panels">
<Panel
firstChild="Hey"
secondChild="Let's"
thirdChild="Talk"
onClick={() => this.toggleOpen(1)}
className={`panel panel1 ${this.state.panel1Open ? "open open-active" : ""}`}
/>
<Panel
firstChild="Hey"
secondChild="Give"
thirdChild="Me"
onClick={() => this.toggleOpen(2)}
className={`panel panel1 ${this.state.panel2Open ? "open open-active" : ""}`}
/>
</div>
)
};
}