函数之间的冲突,api没有命中

如何解决函数之间的冲突,api没有命中

我正在使用MERN堆栈和Redux。我创建了一个函数来更新数据库中的属性。我已经在Postman上测试了api,并且可以正常工作。当我尝试运行它时,似乎与另一个函数发生冲突,并且出现错误“ TypeError:this.props.subjects.map不是一个函数”,该错误在调用trueVote函数之前起作用。有人知道我在这里想念什么吗?

打印输出显示动作和减速器被击中,但api没有击中,即使在Postman上也是如此。该函数是从表决处理程序中调用的

编辑:不打印api中的console.log消息,但在我在错误后刷新页面后,VS的终端窗口中显示该函数已完成应做的工作,并且相关数据已更新。是管理错误的情况吗?如果是这样,我该怎么做,这样才不会使应用程序崩溃?

api

// put req for a true vote
subjectRouter.put("subject/true/:_id/:currTrue",(req,res) => {
  console.log("True api hitting");
  Subject.findOneAndUpdate(
    { _id: req.params._id },{
      true: Number(req.params.currTrue) + 1,},{
      new: true,useFindAndModify: false,}
  )
    .then((subject) => res.json(subject))
    .catch((err) => console.log(err));
});

动作

// true vote
export const trueVote = (_id,currTrue) => (dispatch) => {
  console.log("trueVote hitting");
  fetch(`/api/subjects/subject/true/${_id}/${currTrue}`,{
    method: "PUT",})
    .then((res) => res.json())
    .then((subject) =>
      dispatch({
        type: TRUE_VOTE,subjects: subject,})
    );
};

减速器

case TRUE_VOTE:
      console.log("true reducer hitting");
      return {
        ...state,items: action.subjects,};

组件

import React,{ Component } from "react";
import PropTypes from "prop-types";
import GoogleSearch from "./GoogleSearch";
import { connect } from "react-redux";
import { fetchLatestSubjects } from "../../actions/subject";
import { fetchTopicSubjects } from "../../actions/subject";
import { fetchTopicComments } from "../../actions/comment";
import { fetchComments } from "../../actions/comment";
import { rateSubject } from "../../actions/subject";
import { fetchUsers } from "../../actions/authActions";
import { rateUser } from "../../actions/authActions";
import { rateComment } from "../../actions/comment";
import { trueVote } from "../../actions/subject";
import { falseVote } from "../../actions/subject";

class Subject extends Component {
  // on loading the subjects and comments
  // are fetched from the database
  componentDidMount() {
    this.props.fetchLatestSubjects();
    this.props.fetchComments();
    this.props.fetchUsers();
  }

  constructor(props) {
    super(props);
    this.state = {
      // set inital state for subjects
      // description,summary and comments all invisible
      viewDesription: -1,viewSummary: -1,comments: [],topic: "subjects",};
  }

  componentWillReceiveProps(nextProps) {
    // new subject and comments are added to the top
    // of the arrays
    if (nextProps.newPost) {
      this.props.subjects.unshift(nextProps.newPost);
    }
    if (nextProps.newPost) {
      this.props.comments.unshift(nextProps.newPost);
    }
  }

  clickHandler = (id) => {
    // when a subject title is clicked pass in its id
    const { viewDescription } = this.state;
    this.setState({ comments: [] });
    var temp = [];

    // get the details of the author of the subject and save to state
    const subject = this.props.subjects.find((subject) => subject._id === id);
    const user = this.props.users.find((user) => user._id === subject.author);

    // save comments for subject to temp array
    var i;
    for (i = 0; i < this.props.comments.length; i++) {
      if (this.props.comments[i].subject === id) {
        temp.unshift(this.props.comments[i]);
      }
    }

    console.log(temp);
    // for each comment add a property with the authors name
    temp.forEach((comment) => {
      var commentAuthor = this.props.users.find(
        (user) => user._id === comment.author
      );
      comment.authName = commentAuthor.name;
    });

    // save the subject id to local storage
    // this is done incase a new comment is added
    // then the subject associated  with it can be retrieved
    // and added as a property of that comment
    localStorage.setItem("passedSubject",id);
    localStorage.setItem("passedTopic",subject.topic);
    // add all changes to the state
    this.setState({
      viewDescription: viewDescription === id ? -1 : id,comments: temp,subAuthor: user.name,authRating: user.rating,authNoOfVotes: user.noOfVotes,});
  };

  // hovering on and off subjects toggles the visibility of the summary
  hoverHandler = (id) => {
    this.setState({ viewSummary: id });
  };
  hoverOffHandler = () => {
    this.setState({ viewSummary: -1 });
  };

  rateHandler = (id,rate,item) => {
    if (item === "subject") {
      // this function rates the subject and the author
      const subject = this.props.subjects.find((subject) => subject._id === id);
      const author = this.props.users.find(
        (user) => user._id === subject.author
      );
      // call the rateSubject and rateUser functions
      this.props.rateSubject(id,subject.noOfVotes,subject.rating);
      this.props.rateUser(author._id,author.noOfVotes,author.rating);
      console.log(author.name);
      alert("Thank you for rating this subject.");
    } else if (item === "comment") {
      const comment = this.props.comments.find((comment) => comment._id === id);
      const author = this.props.users.find(
        (user) => user._id === comment.author
      );
      // call the rateComment and rateUser functions
      this.props.rateComment(id,comment.noOfVotes,comment.rating);
      this.props.rateUser(author._id,author.rating);
      console.log(author.name);
      alert("Thank you for rating this comment.");
    }
  };

  voteHandler = (id,currVote,vote) => {
    if (vote == "True") {
      console.log(id,vote);
      this.props.trueVote(id,currVote);
    } else if (vote == "False") {
      console.log(id,vote);
      this.props.falseVote(id,currVote);
    }
  };

  render() {
    const subjectItems = this.props.subjects.map((subject) => {
      // if the state equals the id set to visible if not set to invisible
      var view = this.state.viewDescription === subject._id ? "" : "none";
      var hover = this.state.viewSummary === subject._id ? "" : "none";
      var comments = this.state.comments;
      var subjectAuthor = this.state.subAuthor;
      var authRating = this.state.authRating;
      var authNoOfVotes = this.state.authNoOfVotes;
      var className = "";
      if (subject.category === "Education") {
        className = "Education";
      } else if (subject.category === "Environment") {
        className = "Environment";
      } else if (subject.category === "Politics") {
        className = "Politics";
      } else if (subject.category === "Health") {
        className = "Health";
      } else if (subject.category === "Other") {
        className = "Other";
      }

      return (
        <div key={subject._id}>
          <div
            className={className}
            onMouseEnter={() => this.hoverHandler(subject._id)}
            onMouseLeave={() => this.hoverOffHandler()}
          >
            <p className="title" onClick={() => this.clickHandler(subject._id)}>
              {subject.title}
            </p>
            <p className="vote" style={{ textAlign: "Right" }}>
              True:{" "}
              {((100 / (subject.true + subject.false)) * subject.true).toFixed(
                1
              )}
              % {" False: "}
              {((100 / (subject.true + subject.false)) * subject.false).toFixed(
                1
              )}
              %
            </p>
            <p className="summary" style={{ display: hover }}>
              {subject.summary}
            </p>
          </div>

          <div className="subjectBody " style={{ display: view }}>
            <div className="leftSubjectBody">
              <div className="subjectAuthor">
                <p className="author">
                  Subject created by: {subjectAuthor} -{" "}
                  {(authRating / authNoOfVotes).toFixed(1)}/5 Star user
                  {/* <br /> {subject.date} */}
                </p>
              </div>
              <div className="subjectDescription">
                <p className="description">{subject.description}</p>
              </div>

              <div className="subjectLinks">Links: {subject.links}</div>
            </div>
            <div className="rightSubjectBody">
              <div className="rate">
                <p> Rate this subject:</p>
                <br />
                <button
                  onClick={() => this.rateHandler(subject._id,1,"subject")}
                >
                  1
                </button>
                <button
                  onClick={() => this.rateHandler(subject._id,2,"subject")}
                >
                  2
                </button>
                <button
                  onClick={() => this.rateHandler(subject._id,3,"subject")}
                >
                  3
                </button>
                <button
                  onClick={() => this.rateHandler(subject._id,4,"subject")}
                >
                  4
                </button>
                <button
                  onClick={() => this.rateHandler(subject._id,5,"subject")}
                >
                  5
                </button>
                <p>
                  Rating: {(subject.rating / subject.noOfVotes).toFixed(1)}/5
                </p>
              </div>
              <div className="voting">
                <p>
                  Do you think this subject question is true or false based on
                  the evidence provided and your own reseach in the area? <br />
                </p>
                <p>Please vote and leave comments.</p>

                <br />
                <div
                  className="voteButton"
                  onClick={() =>
                    this.voteHandler(subject._id,subject.true,"True")
                  }
                >
                  TRUE
                </div>
                <div
                  className="voteButton"
                  onClick={() =>
                    this.voteHandler(subject._id,subject.false,"False")
                  }
                >
                  FALSE
                </div>
              </div>
            </div>

            <div className="subjectComments">
              <p style={{ fontWeight: "bold" }}>Comments:</p>
              {comments.map((comment,i) => {
                return (
                  <div key={i} className="singleComment">
                    <p>
                      {comment.title}
                      <br />
                      {comment.comment}
                      <br />
                      Comment by : {comment.authName} - This user has a rating
                      of {(comment.rating / comment.noOfVotes).toFixed(1)}/5
                      STARS
                    </p>
                    <div className="rate">
                      Rate this comment:
                      <button
                        onClick={() =>
                          this.rateHandler(comment._id,"comment")
                        }
                      >
                        1
                      </button>
                      <button
                        onClick={() =>
                          this.rateHandler(comment._id,"comment")
                        }
                      >
                        2
                      </button>
                      <button
                        onClick={() =>
                          this.rateHandler(comment._id,"comment")
                        }
                      >
                        3
                      </button>
                      <button
                        onClick={() =>
                          this.rateHandler(comment._id,"comment")
                        }
                      >
                        4
                      </button>
                      <button
                        onClick={() =>
                          this.rateHandler(comment._id,"comment")
                        }
                      >
                        5
                      </button>
                      <p>
                        Rating:{" "}
                        {(comment.rating / comment.noOfVotes).toFixed(1)}/5
                      </p>
                    </div>
                  </div>
                );
              })}
              <br />
              <a href="/addcomment">
                <div className="buttonAddComment">ADD COMMENT</div>
              </a>
            </div>
          </div>
        </div>
      );
    });

    return (
      <div id="Subject">
        <GoogleSearch />
        {subjectItems}
      </div>
    );
  }
}

Subject.propTypes = {
  fetchLatestSubjects: PropTypes.func.isRequired,fetchTopicSubjects: PropTypes.func.isRequired,fetchTopicComments: PropTypes.func.isRequired,fetchComments: PropTypes.func.isRequired,fetchUsers: PropTypes.func.isRequired,rateSubject: PropTypes.func.isRequired,rateComment: PropTypes.func.isRequired,rateUser: PropTypes.func.isRequired,trueVote: PropTypes.func.isRequired,falseVote: PropTypes.func.isRequired,subjects: PropTypes.array.isRequired,comments: PropTypes.array.isRequired,users: PropTypes.array.isRequired,newPost: PropTypes.object,};

const mapStateToProps = (state) => ({
  subjects: state.subjects.items,newSubject: state.subjects.item,comments: state.comments.items,users: state.auth.users,newComment: state.comments.item,});

// export default Subject;
export default connect(mapStateToProps,{
  fetchLatestSubjects,fetchTopicSubjects,fetchTopicComments,fetchComments,fetchUsers,rateSubject,// rate subject
  rateUser,rateComment,trueVote,falseVote,})(Subject,Comment);

解决方法

由于作为归约器操作的一部分,您将返回一个subject,因此您可能想将现有的subject与更新后的subject进行交换,因此您需要更新归约器成为:

case TRUE_VOTE:
  const index = state.items.subjects.findIndex( subject => action.subjects.id === subject.id );
  return {
    items: [...state.items.slice(0,index),action.subjects,...state.items.slice( index + 1 )] };
  };

为了更清楚一点,您当然也可以更改操作以表明它只是您要返回的单个主题

// true vote
export const trueVote = (_id,currTrue) => (dispatch) => {
  console.log("trueVote hitting");
  fetch(`/api/subjects/subject/true/${_id}/${currTrue}`,{
    method: "PUT",})
    .then((res) => res.json())
    .then((subject) =>
      dispatch({
        type: TRUE_VOTE,subject
      })
    );
};

然后在减速器中更清楚地知道您仅期望1个主题

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-