在 React 中单击组件时向兄弟姐妹添加类
Posted
技术标签:
【中文标题】在 React 中单击组件时向兄弟姐妹添加类【英文标题】:Add class to siblings when Component clicked in React 【发布时间】:2017-09-12 09:37:51 【问题描述】:我正在使用 React.js 构建我的作品集。在一个部分中,我将四个组件布置在一个网格中。我想要实现的是,当单击一个组件时,将一个 css 类添加到该组件的兄弟姐妹中,以降低它们的不透明度,并且只保留单击的组件。在 jQuery 中,它类似于 $('.component').on('click', function() $(this).siblings.addClass('fadeAway'))。我怎样才能达到这个效果?这是我的代码,在此先感谢您的帮助!
class Parent extends Component
constructor()
super();
this.state = fadeAway: false
this.handleClick = this.handleClick.bind(this)
handleClick()
//Add class to siblings
render()
const array = ["Hello", "Hi", "How's it going", "Good Times"]
return(
array.map(function(obj, index)
<Child text=obj key=index onClick=() => this.handleClick />
)
)
【问题讨论】:
【参考方案1】:这个问题的一个工作示例可能看起来像这样,具有稍微复杂的初始化数组:
class Parent extends Component
constructor()
super();
this.state =
elements: [
id: "hello",
text: "Hello",
reduced: false,
,
id: "hi",
text: "Hi",
reduced: false,
id: "howsItGoing"
text: "How's it going",
reduced: false,
id: "goodTimes",
text: "Good Times",
reduced: false,
],
this.handleClick = this.handleClick.bind(this)
handleClick(e)
// copy elements from state
const elements = JSON.parse(JSON.stringify(elements));
const newElements = elements.map(element =>
if (element.id === e.target.id)
element.reduced = false;
else
element.reduced = true;
);
this.setState(
elements: newElements,
);
render()
return(
this.state.elements.map(function(obj, index)
<Child
id=obj.id
text=obj.text
reduced=obj.reduced
key=index
onClick=() => this.handleClick />
);
);
然后您只需像这样向Child
组件添加一个三元组:
<Child
id=this.props.id
className=this.props.reduced ? "reduced" : "" />
这比其他示例添加了更多样板文件,但是将业务逻辑与组件内的文本联系起来非常脆弱,并且更强大的解决方案需要更强大的标识,例如呈现的 DOM 元素上的 ID 或类。如果您愿意,此解决方案还可以让您轻松扩展逻辑,以便多个元素一次保持最大不透明度。
【讨论】:
这个解决方案实际上帮助最大。起初,我所做的事情似乎有点健壮,但你真的很好地解释了它,现在对我来说完全有意义。我不得不稍微调整一下 handleClick 函数,并且不需要使用 JSON.parse,但总体概念有效,我实现了最终目标。谢谢!! @furkle @IanSpringer 很高兴为您提供帮助!【参考方案2】:我将简单地存储在所选项目的状态索引中,然后将fadeAway
prop 传递给定义为
fadeAway=this.state.selectedIndex !== index
之后你只需要基于this.prop.fadeAway
在Child中设置一个fade-away
类并定义必要的CSS规则。
以下是您的情况:
class Parent extends React.Component
constructor ()
super();
this.state = selectedIndex: null
handleClick (selectedIndex)
this.setState( selectedIndex )
render ()
const array = ["Hello", "Hi", "How's it going", "Good Times"]
return (
<div>
array.map((obj, index) =>
const faded = this.state.selectedIndex && this.state.selectedIndex !== index
return <Child
text=obj
fadeAway=faded
key=index
onClick=() => this.handleClick(index) />
)
</div>
)
class Child extends React.Component
render ()
return (
<h2
onClick=this.props.onClick
className=this.props.fadeAway ? 'fade-away' : ''>
this.props.text
</h2>
)
ReactDOM.render(
<Parent />,
document.body
);
.fade-away
opacity: 0.3;
<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>
【讨论】:
谢谢,这似乎很接近。但是,当页面呈现时,我希望所有组件都具有完全不透明度。当一个被点击时,其他的应该会失去它们的不透明度。此解决方案将一个组件设置为在页面加载时处于活动状态,此时它们都应该处于活动状态,直到单击一个组件。有什么建议吗? @IanSpringer 当然,只需将默认的selectedIndex
设为null
并在const faded = this.state.selectedIndex && this.state.selectedIndex !== index
中检查它。查看演示。【参考方案3】:
您可以使用切换变量来实现:
handleClick()
this.setState(fadeAway => (
fadeAway: ! fadeAway
);
...
<Child
text=obj
key=index
onClick=() => this.handleClick
className=this.state.fadeAway? 'class1' : 'class2'/>
【讨论】:
谢谢,但这个解决方案似乎切换了目标组件的类。我需要为单击的组件的兄弟姐妹添加一个新类。【参考方案4】:我更喜欢使用currentWord
这样的状态来保存在父组件中被点击的单词,presudo代码如下:
class Parent extends Component
constructor()
super();
this.state =
fadeAway: false,
currentWord: ''
;
this.handleClick = this.handleClick.bind(this)
handleClick(currentWord)
this.setState(
currentWord: currentWord,
);
render()
const array = ["Hello", "Hi", "How's it going", "Good Times"]
const currentWord = this.state.currentWord;
return(
array.map(function(obj, index)
<Child currentWord=currentWord text=obj key=index onClick=() => this.handleClick />
)
)
在子组件中
class Child extends Component
// some other code
handleClick(e)
this.props.handleClick(e.target.value);
render()
const isSelected = this.props.text === this.props.currentWord;
// use isSelected to toggle className
<div
onClick=this.handleClick.bind(this)
>this.props.text
</div>
【讨论】:
您将 prop 传递为currentWord
,但在子组件中将其引用为 CurrentWord
。以上是关于在 React 中单击组件时向兄弟姐妹添加类的主要内容,如果未能解决你的问题,请参考以下文章