切换 div 的背景颜色

IT技术 javascript css reactjs
2021-05-08 15:57:38

我正在映射一个 div,因此它会根据我在我的数据库中拥有的数据量来呈现。就我而言,我的 div 渲染了 4 次。(这是一个有 4 个选项的民意调查。)

我将逐步解释我的问题。

1)我想为与我在页面加载时从数据库中获取的 id 匹配的 div 设置背景颜色。我是这样做的

    componentDidMount() {

            let sel3 = document.getElementById(this.props.voted_id);

            if (sel3) {

                sel3.style.backgroundColor = "#0b97c4";
                sel3.style.color = "#FFFFFF";
            }
        }

this.props.voted_id是我从数据库中获取的 ID。(这是用户选择的投票选项的 ID。所以在 componentDidMount 上,我通过设置背景颜色来显示所选选项)

2) 如果用户想改变他/她的选择,用户可以通过点击新的选择来改变它。我想为用户选择的新选项设置背景颜色,同时我想删除以前选择的选项的背景颜色。我这样做

我的组件

render() {

        let {contents, submitvote, postId, voted_id} = this.props

        return (

            <div className="txt_vote_bar_div" id={this.props.contents.post_poll_content_id}>
                <p className="txt_vote_choice" id={this.props.contents.post_poll_content_id}
                   onClick={() => {
                       this.handleClick(this.props.contents.post_poll_content_id);
                   }}>
                    {contents.content}
                </p>
                <p className="txt_tot_votes"> {this.props.contents.votes_percentage}%
                    ({this.state.voteCount} Votes)</p>
            </div>
        );
    };

在 handleClick 功能上,我正在执行以下操作

 handleClick(id) {

        let sel = document.getElementById(this.props.voted_id);
    if (sel) {
        alert("1");
        sel.style.backgroundColor = "#FFFFFF";
        sel.style.color = "#6a6a6a";
    }

    let sel2 = document.getElementById(this.props.getVoteStatus);
    if (sel2) {
        alert("2");
        sel2.style.backgroundColor = "#FFFFFF";
        sel2.style.color = "#6a6a6a";
    }

    let el = document.getElementById(id);
    if (el) {
        alert("3");
        this.setState({

            active: false,

        })
        el.style.backgroundColor = "#0b97c4";
        el.style.color = "#FFFFFF";
    }



    let sel3 = document.getElementById(id);
    if (sel3.id == this.props.getVoteStatus && this.state.active == false) {
        alert("4");
        this.setState({
            active: true,
        })
        sel3.style.backgroundColor = "#FFFFFF";
        sel3.style.color = "#6a6a6a";
    }

    }

this.props.voted_id是我从数据库中获取的首选 ID(我使用此 ID 设置背景componentDidMount

this.props.getVoteStatus是以前选择的选项 ID,当用户选择新选项时,我使用它来删除背景颜色。

到目前为止,我已经成功地做到了这一点,没有任何问题。但我的问题是这个

当页面加载时,如果我从数据库中获得一个 id,则带有该 id 的特定 div 是彩色的。没关系。但是当用户选择相同的选择时(收回他/她的选择)

这段代码按原样运行(因为用户选择的 div id 与我从数据库中获取的 id 相同)

let sel = document.getElementById(this.props.voted_id);
        if (sel) {
            alert("2");
            sel.style.backgroundColor = "#FFFFFF";
            sel.style.color = "#6a6a6a";
        }

之后这段代码运行

let el = document.getElementById(id);
        if (el) {
            alert("1");
            this.setState({
                active: false,
            })
            el.style.backgroundColor = "#0b97c4";
            el.style.color = "#FFFFFF";
        }

此问题仅在页面加载后出现一次。在那种情况下,代码的两部分都是有效的。因此它运行两者。我该如何解决这个问题?

更新

这就是我映射 div 元素的方式

export const TextVoteList = ({postData, submitvote}) => {

    const dataUnavailable = (
        <div>
            <p>
                There are no voting options available available
            </p>
        </div>
    );

    const dataAvailable = (
        <div>
            {postData.post_poll_content.map(contents => <TextVoteOptions key={contents.post_poll_content_id} voted_id={postData.personal_vote}  contents={contents} submitvote = {submitvote} postId = {postData._id}/>)}
        </div>
    );

    return (

        <div>
            {postData.post_poll_content.length === 0 ? dataUnavailable : dataAvailable}
        </div>

    );
};

TextVoteOptions代码

render() {

        alert(this.props.getVoteResponse);

        let {contents, submitvote, postId, voted_id} = this.props

        return (


            <div key={this.props.contents.post_poll_content_id} className= {(this.state.voted_id === this.props.contents.post_poll_content_id && this.state.active)  ? "txt_vote_bar_div active" :  "txt_vote_bar_div"}>
                <p className="txt_vote_choice" id={this.props.contents.post_poll_content_id}
                   onClick={() => {
                       this.handleClick(this.props.contents.post_poll_content_id);
                   }}>
                    {contents.content}
                </p>
                <p className="txt_tot_votes"> {this.props.contents.votes_percentage}%
                    ({this.state.voteCount} Votes)</p>
            </div>
        );
    };

我的点击处理程序

handleClick(id) {

        let vote_object = {
            voting_object: id,
            post_id: this.props.postId
        }

        this.setState({
            voted_id: id,
            active: (id != this.state.voted_id) ? true : !this.state.active
        });


        this.props.submitvote(vote_object);

    }
1个回答

您应该避免自己进行实际的 DOM 操作。让 React 来处理实际的 DOM 操作。根据我的理解,我设计如下。请尝试联系。希望这可以帮助。

在你的问题中,我不明白状态“活动”的用法,所以我没有在下面的片段中使用。这就是你想要达到的目标吗?

const contents = [
  {
    post_poll_content_id: 1,
    content: "Soccer",
    votes_percentage: 60
  },
  {
    post_poll_content_id: 2,
    content: "Cricket",
    votes_percentage: 20
  },
  {
    post_poll_content_id: 3,
    content: "Basketball",
    votes_percentage: 20
  }
];

const votedId = 3; // Assume this is coming from database;

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      voteCount: 100,
      voted_id: props.voted_id,
      active:true
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(id) {
    this.setState({
        voted_id: id,
        active: (id != this.state.voted_id) ? true : !this.state.active
    });
    
  }

  render() {
   let {contents, voted_id} = this.props;
    return (
      <div>
        {contents.map((content, index) => {
          return (
            <div key={index} className= {(this.state.voted_id===content.post_poll_content_id && this.state.active)  ? "txt_vote_bar_div active" :  "txt_vote_bar_div"}
                 id={content.post_poll_content_id}
            >
              <p
                className="txt_vote_choice"
                id={content.post_poll_content_id}
                onClick={() => {
                  this.handleClick(content.post_poll_content_id);
                }}
              >
                {content.content}
              </p>
              <p className="txt_tot_votes">
                {content.votes_percentage % this.state.voteCount} Votes
              </p>
            </div>
          );
        })}
      </div>
    );
  }
}
ReactDOM.render(<Demo contents={contents} voted_id = {votedId}/>, document.getElementById("app"));
.txt_vote_bar_div {
   display:block;
   border:1px solid #eee;
   margin: 10px;
   width:20%;
   text-align:center;
}

.active {
  background-color:#0b97c4;
  color:#FFF;
}

.txt_vote_choice {
   color:'blue';
   cursor:pointer;
   text-decoration:underline;
}
<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>

<div id="app"></div>