首页 > 解决方案 > 如何让我的 React like 按钮在不喜欢时增加,然后在喜欢时减少?

问题描述

状态变量likes只是继续增加。我以为我的onSelect函数可以交替 的布尔值liked,但显然不是。

这是错误:

Error: 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.

这是 App.js:

import React, { useState } from 'react';
import './App.css';
import LikeButton from './components/LikeButton';

function App() {
  const [likes, updateLikes] = useState(23);
  const [liked, updateLiked] = useState(false);

  return (
    <LikeButton 
    secret='like-button'
    numLikes={likes}
    liked={liked}
    // status={liked}
    onSelect={function clickLike(liked) { //This function is happening, but the else block
      // never fires.
      if (liked) {
        updateLikes(likes + 1);
       } else { updateLikes(likes - 1)
       };
      updateLiked(!liked);
      }
    }
    />
    // onClick function here, or in LikeButton.js?
  );
}

export default App;

这是 LikeButton.js:

import React from 'react';
import { FaThumbsUp } from 'react-icons/fa';

export default function LikeButton({secret, liked, numLikes, onSelect}) {
    return (
      <>
        <FaThumbsUp />
        <div key={secret} liked={liked} onClick={onSelect(liked)}>Like Button</div>
        <p>{numLikes}</p>
      </>
    );
}

标签: reactjsbuttoncomponentsstate

解决方案


问题

您立即调用您的onClick回调,它会更新父级中的状态。

import React from 'react';
import { FaThumbsUp } from 'react-icons/fa';

export default function LikeButton({secret, liked, numLikes, onSelect}) {
    return (
      <>
        <FaThumbsUp />
        <div
          key={secret}
          liked={liked}
          onClick={onSelect(liked)} // invoked right away
        >
          Like Button
        </div>
        <p>{numLikes}</p>
      </>
    );
}

解决方案

使其成为匿名内部函数。

import React from 'react';
import { FaThumbsUp } from 'react-icons/fa';

export default function LikeButton({secret, liked, numLikes, onSelect}) {
    return (
      <>
        <FaThumbsUp />
        <div
          key={secret}
          liked={liked}
          onClick={() => onSelect(liked)} // invoked when clicked
        >
          Like Button
        </div>
        <p>{numLikes}</p>
      </>
    );
}

建议

当下一个状态值取决于当前状态值时,您还应该真正使用功能状态更新,即在递增/递减计数或切换布尔值时。我还建议将其移动updateLikes到一个useEffect钩子中以对liked切换做出反应。这可能会使关于递增/递减的逻辑更加清晰。

function App() {
  const [likes, updateLikes] = useState(23);
  const [liked, updateLiked] = useState(false);

  useEffect(() => {
    updateLikes(likes => likes + (liked ? 1 : -1));
  }, [liked]);

  return (
    <LikeButton 
      secret='like-button'
      numLikes={likes}
      liked={liked}
      // status={liked}
      onSelect={function clickLike(liked) {
        updateLiked(liked => !liked);
      }}
    />
  );
}

推荐阅读