首页 > 解决方案 > 我如何只在 React JS 中重新渲染“Like”按钮?

问题描述

const SiteDetails = ({site, user}) => {
  const dispatch = useDispatch()

  const updateSite = async (siteId, siteObject) => {
    try {
      const updatedSite = await siteService.update(siteId, siteObject)
      dispatch(toggleStatus(siteId, updatedSite))
      // dispatch(setNotification(`One like added to ${updatedSite.title}`))
    } catch (exception) {
      console.log(exception)
      dispatch(setNotification("Could not update site"))
    }
  }


  return (
    <div className='site-details'>
      <Link href={site.url}>{site.url}</Link>
      <h2>
        <LikeButton user={user} site={site} updateSite={updateSite} />
        <VisitButton user={user} site={site} updateSite={updateSite} />
      </h2>
      <p>{site.description}</p>
      <img src={site.imageUrl} alt={"Image could not be loaded"} />
    </div>
  )
}

const LikeButton = ({user, site, updateSite}) => {

  const dispatch = useDispatch()
  const likedList = site?.userLiked.find(n => n?.username === user.username)
  useEffect(() => {
    if (!likedList) {
      const newUser = { username: user.username, liked: false }
      const updatedArray = site.userLiked.concat(newUser)
      const updatedSite = {...site, userLiked: updatedArray}
      updateSite(site.id, updatedSite)
    }  
  },[])


  const liked = likedList?.liked

  const handleLike = async () => {
    const indexCurr = site.userLiked.indexOf(likedList)
    //updatedSite is the parent site. This will have its liked status toggled
    //actually updatedUserLiked can simply use username: user.username and liked: true
    const updatedUserLiked = { username: likedList?.username, liked: !likedList.liked}
    site.userLiked[indexCurr] = updatedUserLiked
    const updatedSite = {...site, userLiked: site.userLiked}    
    updateSite(site.id, updatedSite)
    //childSite is the spawned from the parent, 
    //it will contain a parent, which is the updatedSite
    const childSite = {...site, parent: updatedSite, opcode: 100}
    const newSite = await siteService.create(childSite)
    // dispatch(createSite(newSite))
    dispatch(initializeUsers())
    dispatch(initSites())
  }


  return (
    <Button 
      size='small' variant='contained' 
      color={liked ? 'secondary' : 'primary'} 
      onClick={!liked ? handleLike : null} className='site-like'>{liked ? 'Already Liked' : "like"}
    </Button>
  )
}

预期行为 预期行为

实际行为 实际行为

大家好,我的目标是当点击“Like”按钮时,按钮的外观会改变,但页面的其余部分不会刷新。但是,如果您查看实际行为,单击按钮后,页面会重新呈现并恢复到其默认状态。我已经制作了自己的组件,单击后将在下面显示更多详细信息。

我试过查看 React.memo 和 useRef,但没有一个对我有用。对此的帮助将不胜感激。谢谢!

标签: javascriptreactjsreact-redux

解决方案


尝试过使用“useState”钩子吗?

import {useState} from 'react'
function LikeButton() {
    //set default value to false
    const [liked, setLiked] = useState(false);
    const handleClick = () => {setLiked(!liked)}
    return(
        <Button color={liked? 'secondary' : 'primary'} onClick={() => handleClick()} 
    />
    );
}
export default LikeButton;

这应该只重新渲染按钮

也检查一下:

ReactJS - 每次调用“setState”时都会调用渲染吗?


推荐阅读