如何通过检查React JS中的所有数据库值来设置按钮颜色?

时间:2019-07-16 09:31:43

标签: javascript reactjs mongodb

我正在尝试为我的微博客网站创建一个类似/赞的系统(不使用redux)。我已经创建了一个数据库star.js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const StarSchema = new Schema({
  toggled: {
    type: Boolean,
    required: false,
    default: false
  },
  postId: {
    type: String,
    required: true
  },
  userId: {
    type: String,
    required: true
  }
});

module.exports = Star = mongoose.model("Star", StarSchema);

在StarButton.jsx文件中,我有一个星形按钮组件。如果特定用户按下了此按钮,那么将向star数据库发出发布请求。现在,如果用户永久单击按钮,我想显示红色。 我正在做的是,我正在使用map函数来检查star数据库中是否存在用户ID和发布ID,并通过更新状态值将颜色设置为等于红色。 我想说明的是,不同的用户将有不同的帖子按钮,它们已切换。

import React, { Component } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faStar } from "@fortawesome/free-solid-svg-icons";
import axios from "axios";
import { connect } from "react-redux";
import { logoutUser } from "../actions/authActions";
import PropTypes from "prop-types";

class StarButton extends Component {
  constructor(props) {
    super(props);
    this.state = {
      btnColor: "#bcc1c6",
      toggled: false,
      postId: "",
      userId: "",
      starCount: 0,
      starData: []
    };
  }


  componentDidMount() {
    const { user } = this.props.auth;
    this.setState({
      postId: this.props.postId,
      userId: user.id
    });

    axios.get("http://localhost:5000/api/stars")
    .then(res => res.data)
    .then( data => { this.setState({ starData: data }) } )
  }

  btnToggled = () => {
    const { user } = this.props.auth;
    const starPackage = {
      toggled: true,
      postId: this.props.postId,
      userId: user.id
    }

    axios.post("http://localhost:5000/api/stars",
    {
      toggled: starPackage.toggled,
      postId: starPackage.postId,
      userId: starPackage.userId
    },
    {
      headers: {
        "content-type": "application/json"
      }
    }
    )
    .then("Star toggle submitted by " + starPackage.userId)
    .catch(console.log(err => "Error !!" + err));
  };

  starCount(){
    console.log("star count function gives " + this.props.postId);
  }

  starCheck(postId, userId) {
    const {user} = this.props.auth;
    console.log("Match" + this.props.postId, user.id);
    console.log("with " + postId, userId);
    if( postId.toString() === this.props.postId.toString() && userId.toString() === user.id.toString()){
       this.setState({ btnColor: "red" })   // Here I am setting the state value
      return "red"
    }

  }

  render() {
    const starColor = this.state.starData.map(star => ( this.starCheck(star.postId, star.userId) ));

      console.log("Star color issss " + starColor);
    return (
      <div>


        <button
          style={{ color: this.state.btnColor }}
          className="btn btn-light"
          onClick={this.btnToggled}
        >
          {" "}
          <span>
            <FontAwesomeIcon icon={faStar} />
            <span> {this.state.stars} </span>
            <p style = {{ fontSize: "small" }}>24</p>
          </span>

        </button>
      </div>
    );
  }
}


StarButton.propTypes = {
  logoutUser: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { logoutUser }
)(StarButton);

但是我面临以下错误

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
starCheck
src/component/StarButton.jsx:68

  65 |   console.log("Match" + this.props.postId, user.id);
  66 |   console.log("with " + postId, userId);
  67 |   if( postId.toString() === this.props.postId.toString() && userId.toString() === user.id.toString()){
> 68 |      this.setState({ btnColor: "red" })
     | ^  69 |     return "red"
  70 |   }
  71 | 

该方法是否可以解决,因为我的代码/逻辑似乎有点破旧(我是新手)。

1 个答案:

答案 0 :(得分:0)

您无需将颜色值保存为状态,而只需在渲染器中进行计算即可:

 starCheck = (postId, userId) => {
    const {user} = this.props.auth;

    if( postId.toString() === this.props.postId.toString() && userId.toString() === user.id.toString()){
       return "red"
    }

     return this.state.btnColor
  }

,然后在渲染中:


        <button
          style={{ color: this.starCheck(this.props.postId, this.props.auth.user.id) }}
          className="btn btn-light"
          onClick={this.btnToggled}
        >