最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React useState() boolean toggle component adding instead of replacing values - Stack Overflow

programmeradmin2浏览0评论

I've created a mock social media website where users can ment and "like" posts, and so I want to have a button with a thumbs up that will toggle between "liked" and "not liked". Problem is, when I click, the state value (unliked) is joined by the setState value(liked) intead of replaced. Where am I going wrong?

import React, { useState } from 'react';
import ThumbUpIcon from '@material-ui/icons/ThumbUp';

const ThumbUpButton = {
  backgroundColor: 'rgb(115, 250, 179)',
  border: 'none',
  borderRadius: '5px',
}

const ThumbStyle = {
  backgroundColor: 'red',
  border: 'none',
  padding: '5px',
  borderRadius: '5px',
  margin: '1rem'
}

const Liker = () => {
  const [thumb, setThumbUp] = useState(false);

  return (
    <>
      <button style={{border: 'none', backgroundColor: 'transparent'}} onClick={() => setThumbUp(!thumb)}>
        <ThumbUpIcon style={ThumbStyle} />
        {thumb && <ThumbUpIcon style={ThumbUpButton} />}
      </button>
    </>
  );
}

export default Liker;

I've created a mock social media website where users can ment and "like" posts, and so I want to have a button with a thumbs up that will toggle between "liked" and "not liked". Problem is, when I click, the state value (unliked) is joined by the setState value(liked) intead of replaced. Where am I going wrong?

import React, { useState } from 'react';
import ThumbUpIcon from '@material-ui/icons/ThumbUp';

const ThumbUpButton = {
  backgroundColor: 'rgb(115, 250, 179)',
  border: 'none',
  borderRadius: '5px',
}

const ThumbStyle = {
  backgroundColor: 'red',
  border: 'none',
  padding: '5px',
  borderRadius: '5px',
  margin: '1rem'
}

const Liker = () => {
  const [thumb, setThumbUp] = useState(false);

  return (
    <>
      <button style={{border: 'none', backgroundColor: 'transparent'}} onClick={() => setThumbUp(!thumb)}>
        <ThumbUpIcon style={ThumbStyle} />
        {thumb && <ThumbUpIcon style={ThumbUpButton} />}
      </button>
    </>
  );
}

export default Liker;
Share Improve this question asked Aug 28, 2021 at 22:25 MarkohanMarkohan 1422 silver badges12 bronze badges 1
  • 1 Your state seems to be fine but it seems like you don't want to render the first ThumbUpIcon if thumb is true? Try changing the first one to {!thumb && <ThumbUpIcon style={ThumbStyle} />} – digitalbreed Commented Aug 28, 2021 at 22:28
Add a ment  | 

4 Answers 4

Reset to default 3

If I understand your question, you are asking why both a thumbs up and thumbs down sometimes render at the same time. This is because you unconditionally render the thumbs up, and conditionally render the thumbs down.

You should render one or the other. Since it's the same ponent and you are only swapping the style, then conditionally apply one or the other styling.

Additionally, it is mon to use a functional state update when toggling a boolean state value since the next state necessarily depends on the previous state, i.e. thumb => !thumb. This avoids stale state enclosures in callbacks.

<button
  style={{
    border: 'none',
    backgroundColor: 'transparent'
  }}
  onClick={() => setThumbUp(thumb => !thumb)}
>
  <ThumbUpIcon style={thumb ? ThumbStyle : ThumbUpButton} />
</button>

Please set the value directly

onClick={() => setThumbUp(!thumb)}

change this might work using functinal set state

onClick={() => setThumbUp(s=>!s)}

Firstly you should update your state via callbacksetThumbUp ((thumb) => !thumb), secondly you have the problem in this line <ThumbUpIcon style={ThumbStyle} />, this JSX get rendered either the button like clicked or not, so you have to put a condition on it:

import React, { useState } from 'react';
import ThumbUpIcon from '@material-ui/icons/ThumbUp';

const ThumbUpButton = {
  backgroundColor: 'rgb(115, 250, 179)',
  border: 'none',
  borderRadius: '5px',
};

const ThumbStyle = {
  backgroundColor: 'red',
  border: 'none',
  padding: '5px',
  borderRadius: '5px',
  margin: '1rem',
};

const Liker = () => {
  const [thumb, setThumbUp] = useState(false);
  const style = thumb ? ThumbUpButton : ThumbStyle;

  return (
    <>
      <button
        style={{ border: 'none', backgroundColor: 'transparent' }}
        onClick={() => setThumbUp((thumb) => !thumb)}
      >
        <ThumbUpIcon style={style} />
      </button>
    </>
  );
};

export default Liker;
发布评论

评论列表(0)

  1. 暂无评论