【问题标题】:Avoid multiple useEffect on component on component load避免对组件加载多个 useEffect
【发布时间】:2020-11-14 00:36:01
【问题描述】:

我在我的 react 应用中构建了一个简单的点赞书签功能。

const [liked, setLiked] = useState();
const [bookmarked, setBookmarked] = useState();

  useEffect(() => {
    post.liked ?  setLiked(true):  setLiked(false);
    post.bookmarked ?  setBookmarked(true) : setBookmarked(false);
  }, []);

  useEffect(() => {
    axios.post(`${baseURL}/content/like`).then((res) => console.log(res));
  }, [liked]);

每当组件被加载时,useEffect 就会运行两次

如何避免初始 axios post 和 axios post 仅在状态更改时?

我想在liked 状态发生变化时发送一个帖子请求。

【问题讨论】:

    标签: reactjs axios react-hooks


    【解决方案1】:

    您无法避免多次执行useEffect 挂钩。每次liked的值发生变化时都会调用该函数,但是,您可以在调用axios.post之前检查liked的值,以防止对喜欢状态的初始化状态发出请求:

    const [liked, setLiked] = state(false);
    ...
    useEffect(() => {
      if (liked) {
        axios.post(`${baseURL}/content/like`).then(res => console.log(res));
      }
    }, [liked]);
    

    【讨论】:

    • 我在同一个 axios.post 中同时处理喜欢和不喜欢,所以即使喜欢是假的,我也想将它发送到服务器以删除喜欢
    • 附带说明,我还建议在 try catch 中使用 async await。始终捕获异步调用的错误。您的服务器可能已关闭,您可能希望给用户一些错误响应。
    • @SudhakarBehera 你也应该给你的状态一个默认值,因为你不希望它从undefined 设置为false,因为这是一个状态变化并且会触发状态变化. const [liked, setLiked] = useState(false);
    • @JoeLloyd,是的,我正在使用异步等待,出于提问目的,我做的很短
    • 我已经更新了答案,我想如果您在状态下将其设置为假,则无需检查喜欢为真
    【解决方案2】:

    假设post.liked 是后端的当前值,并且您在单击按钮或其他操作时调用setLiked,我会比较状态值是否与当前后端值不同:

    const [liked, setLiked] = useState(post.liked);
    
    useEffect(() => {
        if (liked !== post.liked) {
            axios.post(`${baseURL}/content/like`).then((res) => console.log(res));
        }
    }, [liked, post.liked]);
    

    【讨论】:

    • 除此之外,我还想在组件上更改点赞状态,为 UI 突出显示心形图标,但如果我这样做,它会进入无限循环
    • 啊我认为问题在于您没有将初始状态值设置为post.liked,所以每次渲染时,liked 不会等于post.liked,即会导致帖子运行,然后会导致重新渲染等。
    • 我可以有条件地设置 const [liked, setLiked] = useState(false);在 if 条件内?
    • 不,你只是做const [liked, setLiked] = useState(post.liked);
    【解决方案3】:
      const [liked, setLiked] = useState(false);
      const [bookmarked, setBookmarked] = useState(false);
    
      const handleLike = (likeStaus) => {
        setLiked(likeStaus);
        axios.post(`${baseURL}content/like`).then((res) => console.log(res));
      };
      const handleBookmark = (bookmarkStatus) => {
        setBookmarked(bookmarkStatus);
        axios.post(`${baseURL}content/bookmark`).then((res) => console.log(res));
      };
    
    <button
              className={
                liked
                  ? "meta-button btn btn-default text-danger btn-sm"
                  : "meta-button btn btn-default btn-sm"
              }
              onClick={() => handleLike(!liked)}
            >
              <i className="lar la-heart"></i>
            </button>
    

    我最终使用了一个单独的函数来处理喜欢和书签 由于我的 post.liked 是一个用户数组,我需要初始 useEffect [] 来检查数组中的用户

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 2021-10-16
      • 2022-06-29
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多