【问题标题】:How do I get useState to render each time I update the state?每次更新状态时如何让 useState 呈现?
【发布时间】:2021-09-09 07:42:59
【问题描述】:

我有一个升级栏,如果你点击加号按钮,它会增加 10% 的栏。 我正在使用 useEffect 通过过滤从 mongoDB(Mongoose) 返回的内容来获取特定用户的技能。

我创建了一个 refreshHandler 回调函数,我调用它来增加刷新,以便 useEffect 再次向我的后端发出请求,我希望它会再次呈现组件。

它在开始时执行一次,然后再执行一次,然后停止渲染。 (数据库中的变化仍在发生,虽然点击时级别只会上升一次)

App.js

function App() {
  // States
  const [inputText, setInputText] = useState('');
  const [skills, setSkills] = useState([]);
  const [session, setSession] = useState({ auth: false, token: '', user_id: '', refresh: 0 });
  var { isLoggedIn, refresh } = session;

  const userAuth = (data) => {
    setSession({
      auth: true,
      token: data.token,
      user_id: data.user_id,
    });
    console.log('User logged in successfully!');
  };

  const refreshHandler = () => {
    setSession({ ...session, refresh: session.refresh + 1 });
  };

  useEffect(() => {
    console.log('USE EFFECT MOUNTED!!');
    const fetchSkills = async () => {
      const response = await axios.get('http://localhost:3001/api/users/fetchSkills');
      console.log('response: ', response.data);
      setSkills(
        response.data.filter((skill) => {
          if (skill.user_id == session.user_id) {
            return skill;
          }
        })
      );
    };
    fetchSkills();
  }, [refresh]);

这是我在 SkillList 组件中用来显示技能列表的 Skill.js 组件。

技能.js

const Skill = ({ refreshHandler, text, level, skills, skill, setSkills, percent }) => {
  const levelUpHandler = async () => {
    let data = { _id: skill._id, level: skill.level, percent: skill.percent };
    if (skill.percent == 90) {
      data.percent = 0;
      data.level += 1;
    } else {
      data.percent += 10;
    }
    const response = await axios
      .put('http://localhost:3001/api/users/update-skill', data)
      .then(console.log(data))
      .catch((err) => console.log(err));
    refreshHandler();
  };

我尝试使用我找到的 useRef 示例,但最终在循环中呈现/发出 axios 请求。

Node.js 后端 - 路由

router.put('/update-skill', function (req, res) {
  var id = req.body._id;
  var update = { level: req.body.level, percent: req.body.percent };
  console.log(update);
  Skill.findByIdAndUpdate(id, update, { new: true }, (err, res) => {
    if (err) {
      console.log(err);
    } else {
      console.log('Success:', res);
    }
  });
});

主要目标:

  • 每次点击按钮,更新后端技能的百分比/级别(mongoose/ mongoDB Atlas - 这是有效的,但每个技能只有一个请求,技能从 0 到 10% 然后每次连续点击控制台.logs() 10% 而不是上升)。
  • 希望在每次单击按钮时看到进度条增加。

任何帮助将不胜感激,如果需要更多信息才能弄清楚问题,请告诉我。

【问题讨论】:

  • 您能否提供一个在codesandbox或类似平台上可重现的小例子?
  • 同样在 useState 依赖数组中,你可以尝试 session.refresh 而不是 refresh 吗?
  • 遵循这些非常脱节的 sn-ps 相当困难,但根据你的标题,听起来你正在某个地方改变状态。在我看来,在levelUpHandler 内部,您正在改变传递的道具。似乎这可能是相关的。没有Minimal, Complete, and Reproducible Code Example 就很难诊断。您可以更新您的问题以包含所有相关代码吗?如果您可以创建一个 running 代码沙箱来重现我们可以检查和实时调试的问题,那将会很有帮助。

标签: node.js reactjs express mongoose axios


【解决方案1】:

我找到了解决问题的方法! 基本上,当我使用 axios 向我的后端发出 put 请求时,请求正在发送,但后端没有给出任何响应。

通过检查网络选项卡进行诊断,并且该请求处于待处理状态。似乎在 5 个未决请求之后数据库停止了。

为了解决这个问题,我添加了一个 return 语句。

router.put("/update-skill", async (req, res) => {
  var id = req.body._id;
 var update = { level: req.body.level, percent: req.body.percent };
 try {
    var responseData = await Skill.findByIdAndUpdate(id, update, { new: 
true });
 } catch (err) {
   return res
     .status(500)
     .json({ error: "skill was not updated", message: err });
  }
  // This was the missing code I needed!
  return res.json({ response: "Successful", data: responseData });
});

【讨论】:

    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多