簡體   English   中英

有沒有更簡潔的方法來編寫這個 React 代碼?

[英]Is there a cleaner way to write this React code?

第一次使用反應。 編寫一段代碼,我希望我單擊的元素突出顯示,而未選擇的元素則不突出顯示。 基本上,我希望根據我單擊的元素將狀態更改為 true,並將其他狀態切換為 false。

我的問題是,有沒有更優雅的方式來編寫這段代碼? 我最初嘗試基於event.target但我不知道如何將狀態綁定到特定元素。 雖然下面確實適合我的目的,但我想知道是否有一種方法可以更動態地使用 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>
        )
    }
}

是的,您可以在您的狀態中保留突出顯示元素的名稱。

就像是 :

 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> ); } }

您還可以通過迭代數組來改進 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> ) } }

優化方式

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>
    );
  }
}

只需添加和刪除類名:

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);

輸出: 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));
  };

這將切換狀態屬性的布爾值。

getClassName = element =>
    this.state[element] ? 'highlighted' : 'unhighlighted';

這將切換您的className

為了提高可訪問性,您應該添加一個鍵盤事件。 盡管通常不建議在h3等非交互式元素上使用onClick事件。

<h3
 onClick={this.toggleHighlight}
 onKeyPress={this.toggleHighlight}
 role="button"
 id="profileHighlighted"
 className={this.getClassName('profileHighlighted')}
>
  Profile
</h3>

並按照以前的答案中的建議使用map渲染您的列表

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM