[英]Is there a cleaner way to write this React code?
First time using react.第一次使用反应。 Writing a piece of code where I want the element I click on to be highlighted, while the unselected elements get unhighlighted.编写一段代码,我希望我单击的元素突出显示,而未选择的元素则不突出显示。 Basically, I want the state to change to true based on the element I click, and the other states to be toggled to false.基本上,我希望根据我单击的元素将状态更改为 true,并将其他状态切换为 false。
My question is, is there a more elegant to write this code?我的问题是,有没有更优雅的方式来编写这段代码? I originally tried to base it on event.target
but I don't know how to bind a state to a specific element.我最初尝试基于event.target
但我不知道如何将状态绑定到特定元素。 While below does work for my purposes, I do wonder if there's a way to more dynamically use setState without having to write separate methods for each case...虽然下面确实适合我的目的,但我想知道是否有一种方法可以更动态地使用 setState 而不必为每种情况编写单独的方法......
export default class CharacterNav extends Component {
constructor(props) {
super(props);
this.state = {
profileHighlighted: true,
recruitHighlighted: false,
artsHighlighted: false,
talentsHighlighted: false,
affectionHighlighted: false,
}
this.changeProfileHighlight = this.changeProfileHighlight.bind(this);
this.changeRecruitHighlight = this.changeRecruitHighlight.bind(this);
this.changeArtsHighlight = this.changeArtsHighlight.bind(this);
this.changeTalentsHighlight = this.changeTalentsHighlight.bind(this);
this.changeAffectionHighlight = this.changeAffectionHighlight.bind(this);
this.resetNavState = this.resetNavState.bind(this);
}
changeProfileHighlight () {
this.setState({
profileHighlighted: true,
recruitHighlighted: false,
artsHighlighted: false,
talentsHighlighted: false,
affectionHighlighted: false
});
}
changeRecruitHighlight () {
this.setState({
profileHighlighted: false,
recruitHighlighted: true,
artsHighlighted: false,
talentsHighlighted: false,
affectionHighlighted: false
});
}
changeArtsHighlight () {
this.setState({
profileHighlighted: false,
recruitHighlighted: false,
artsHighlighted: true,
talentsHighlighted: false,
affectionHighlighted: false
});
}
changeTalentsHighlight () {
this.setState({
profileHighlighted: false,
recruitHighlighted: false,
artsHighlighted: false,
talentsHighlighted: true,
affectionHighlighted: false
});
}
changeAffectionHighlight () {
this.setState({
profileHighlighted: false,
recruitHighlighted: false,
artsHighlighted: false,
talentsHighlighted: false,
affectionHighlighted: true
});
}
render () {
let divClass = this.props.characterSelected ?
"blueBackground" :"hideElement";
let profilehighlightclass = this.state.profileHighlighted ? 'highlighted' : 'unhighlighted';
let recruithighlightclass = this.state.recruitHighlighted ? 'highlighted' : 'unhighlighted';
let artshighlightclass = this.state.artsHighlighted ? 'highlighted' : 'unhighlighted';
let talentshighlightclass = this.state.talentsHighlighted ? 'highlighted' : 'unhighlighted';
let affectionhighlightclass = this.state.affectionHighlighted ? 'highlighted' : 'unhighlighted';
return(
<div>
<ul className={divClass}>
<li><h3 onClick={this.changeProfileHighlight} name='profileHighlighted' className={profilehighlightclass}>Profile</h3></li>
<li><h3 onClick={this.changeRecruitHighlight} name='recruitHighlighted' className={recruithighlightclass}>Recruitment</h3></li>
<li><h3 onClick={this.changeArtsHighlight} name='artsHighlighted' className={artshighlightclass}>Arts</h3></li>
<li><h3 onClick={this.changeTalentsHighlight} name='talentsHighlighted' className={talentshighlightclass}>Talents</h3></li>
<li><h3 onClick={this.changeAffectionHighlight} name='affectionHighlighted' className={affectionhighlightclass}>Affection</h3></li>
</ul>
</div>
)
}
}
Yes, you can hold in your state the name of the highlighted element.是的,您可以在您的状态中保留突出显示元素的名称。
something like :就像是 :
export default class CharacterNav extends Component { constructor(props) { super(props); this.state = { highlighted: "profile", }; } setHighlighted = e => { this.setState({ highlighted: e.target.name, }); }; toggleHighlight = selectedTab => { return this.state.highlighted === selectedTab ? "highlighted" : "unhighlighted"; }; render() { let divClass = this.props.characterSelected ? "blueBackground" : "hideElement"; return ( <ul className={divClass}> <li> <h3 onClick={this.setHighlighted} name="profile" className={this.toggleHighlight("profile")} > Profile </h3> </li> <li> <h3 onClick={this.setHighlighted} name="recruit" className={this.toggleHighlight("recruit")} > Recruitment </h3> </li> <li> <h3 onClick={this.setHighlighted} name="arts" className={this.toggleHighlight("arts")} > Arts </h3> </li> <li> <h3 onClick={this.setHighlighted} name="talents" className={this.toggleHighlight("talents")} > Talents </h3> </li> <li> <h3 onClick={this.setHighlighted} name="affection" className={this.toggleHighlight("affection")} > Affection </h3> </li> </ul> ); } }
You can also improve your li rendering by iterating over an array您还可以通过迭代数组来改进 li 渲染
export default class CharacterNav extends Component { constructor(props) { super(props); this.state = { highlighted: 'profile' } this.setHighlighted = this.setHighlighted.bind(this); } setHighlighted(e) { this.setState({ highlighted: e.target.name }); } render () { let divClass = this.props.characterSelected ? "blueBackground" :"hideElement"; return( <div> <ul className={divClass}> ['Profile', 'Recruitment', 'Talents', 'Affection'].map(item => { const name = item.toLowerCase(); return ( <li> <h3 onClick={this.setHighlighted} name={name} className={name === this.state.highlighted ? 'highlighted' : 'unhighlighted'}> {item} </h3> </li> ) }) </ul> </div> ) } }
Optimized way优化方式
class App extends React.Component {
state = {
arr: [
{ id: 1, name: "profileHighlighted", title: "Profile" },
{ id: 2, name: "recruitHighlighted", title: "Recruitment" },
{ id: 3, name: "changeArtsHighlight", title: "Arts" },
{ id: 4, name: "talentsHighlighted", title: "Talents" },
{ id: 5, name: "affectionHighlighted", title: "Affection" }
],
heightlighted:''
};
changeProfileHighlight = id => {
this.setState({heightlighted:id})
};
render() {
return (
<div>
<ul>
{this.state.arr.map(({ name, id, title }) => (
<li>
<h3
onClick={() => this.changeProfileHighlight(id)}
name={name}
className={"profilehighlightclass"}
>
<span style={{color:this.state.heightlighted===id?'red':''}}>{title}</span>
</h3>
</li>
))}
</ul>
</div>
);
}
}
Just add and remove class name :只需添加和删除类名:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const highlightMe=(e)=>{
var els = document.getElementsByClassName("highlight");
for(var i = 0; i < els.length; i++){
els.item(i).classList.remove("highlight");
}
e.target.classList.add("highlight");
}
return (
<div className="App">
<div>
<ul className={''}>
<li><h3 onClick={highlightMe} name='profileHighlighted' className={"profileHighlighted"}>Profile</h3></li>
<li><h3 onClick={highlightMe} name='recruitHighlighted' className={"recruitHighlighted"}>Recruitment</h3></li>
<li><h3 onClick={highlightMe} name='artsHighlighted' className={"artsHighlighted"}>Arts</h3></li>
<li><h3 onClick={highlightMe} name='talentsHighlighted' className={"talentsHighlighted"}>Talents</h3></li>
<li><h3 onClick={highlightMe} name='affectionHighlighted' className={"affectionHighlighted"}>Affection</h3></li>
</ul>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
output : https://codesandbox.io/s/tender-http-pl4xy输出: https : //codesandbox.io/s/tender-http-pl4xy
toggleHighlight = e => {
const copy = { ...this.state };
Object.keys(copy).forEach(key => (copy[key] = false));
this.setState({ ...copy, [e.target.id]: true }, () => console.log(this.state));
};
This will toggle the boolean value of your state properties.这将切换状态属性的布尔值。
getClassName = element =>
this.state[element] ? 'highlighted' : 'unhighlighted';
This will toggle your className
.这将切换您的className
。
To improve accessibility, you should add a keyboard event.为了提高可访问性,您应该添加一个键盘事件。 Albeit it's generally not recommended to have onClick
events on non-interactive elements like h3
.尽管通常不建议在h3
等非交互式元素上使用onClick
事件。
<h3
onClick={this.toggleHighlight}
onKeyPress={this.toggleHighlight}
role="button"
id="profileHighlighted"
className={this.getClassName('profileHighlighted')}
>
Profile
</h3>
And do use map
do render your list as recommended in previous answeres并按照以前的答案中的建议使用map
渲染您的列表
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.