简体   繁体   English

单击 ReactJS 时按钮仅工作一次

[英]Button working only one time on clicking in ReactJS

I have created a random quote machine project in React with functional component.我在 React 中创建了一个带有功能组件的随机报价机项目。 When I click on new quote it works only once.当我点击新报价时,它只工作一次。 This is one of the freecodecamp challenge project.这是 freecodecamp 挑战项目之一。 Here, I am trying to get new quote every time I click on the new quote button.在这里,每次单击新报价按钮时,我都会尝试获取新报价。 I am unable to spot the issue.我无法发现问题。 Please help.请帮忙。

import React, {useState} from "react";
import {Button, Card, Col, Container, Row} from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTwitter } from "@fortawesome/free-brands-svg-icons";

const quotes = [
  {
    quote: "The greatest glory in living lies not in never falling, but in rising every time we fall.",
    author: "Nelson Mandela"
  },
  {
    quote: "The way to get started is to quit talking and begin doing.",
    author: "Walt Disney"
  },
  {
    quote: "Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma – which is living with the results of other people's thinking." ,
    author: "Steve Jobs"
  },
  {
    quote: "If life were predictable it would cease to be life, and be without flavor.",
    author: "Eleanor Roosevelt"
  },
  {
    quote: "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough.",
    author: "Oprah Winfrey"
  },
  {
    quote: "If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success.",
    author: "James Cameron"
  },
  {
    quote: "Life is what happens when you're busy making other plans.",
    author: "John Lennon"
  },
  {
    quote: "Spread love everywhere you go. Let no one ever come to you without leaving happier.",
    author: "Mother Teresa"
  },
  {
    quote: "When you reach the end of your rope, tie a knot in it and hang on.",
    author: "Franklin D. Roosevelt"
  },
  {
    quote: "It is during our darkest moments that we must focus to see the light.",
    author: "Aristotle"
  },
];
const colors = [
  "#ffdecf",
  "#d3dbff",
  "#8fcfd1",
  "#eeecda",
  "#383e56",
  "#89c9b8",
  "#cff6cf",
  "#726a95",
  "#abc2e8",
  "#303960"
];

const rand_num = Math.floor(Math.random()*quotes.length);

export const Quoter = () => {

  const [quote, setQuote] = useState(quotes[0].quote);
  const [author, setAuthor] = useState(quotes[0].author);
  const [color, setColor] = useState(colors[0]);


  const handleQuote = () => {
    return (
      setQuote(quotes[rand_num].quote),
      setAuthor(quotes[rand_num].author),
      setColor(colors[rand_num])
    )
  }


  return (
    <Container id="quote-box">
      <Row className="d-flex justify-content-center align-items-center">
        <Card>
          <Card.Body style={{width: "18rem"}}>
            <Card.Text id="text" style={{color: color}}>
              {quote}
              <Col>
                <p id='author'>-{author}</p>
              </Col>
            </Card.Text>
                <Button id='tweet-quote'><Card.Link href=""><FontAwesomeIcon icon={faTwitter}/></Card.Link></Button>
                <Button id='new-quote'
                        onClick={handleQuote}
                >
                  New Quote
                </Button>
          </Card.Body>
        </Card>
      </Row>
    </Container>
  )
}

Each time you have the same rand_num value inside your component.每次您的组件中都有相同的 rand_num 值。

You need to generate a new value each time and replace const by let.每次都需要生成一个新值,用let替换const。

const handleQuote = () => {
     rand_num = Math.floor(Math.random()*quotes.length);

    return (
      setQuote(quotes[rand_num].quote),
      setAuthor(quotes[rand_num].author),
      setColor(colors[rand_num])
    )
  }

As you are defining your constant rand_num outside of the main component Quoter , the logic is being executed only once, when your code runs for the first time.当您在主要组件Quoter之外定义常量 rand_num 时,该逻辑仅在您的代码第一次运行时执行一次。 This, rand_num always carry the same value.这一点,rand_num 总是携带相同的值。

Moving the variable declaration into the scope of Quoter would solve the issue.将变量声明移动到 Quoter 的scope中将解决该问题。 The best approach would be to place your constant declaration inside handleQuote method.最好的方法是将常量声明放在 handleQuote 方法中。 Also, as a suggestion and for keeping a clear consistency, you shouldn't use return on handleQuote, as you are not really returning any value with the method.此外,作为一个建议并为了保持清晰的一致性,您不应在 handleQuote 上使用 return,因为您并没有真正使用该方法返回任何值。 The code still works fine with return, but it's just technically incorrect.该代码仍然可以正常使用 return,但它在技术上是不正确的。

  const handleQuote = () => {
    const rand_num = Math.floor(Math.random()*quotes.length);

    setQuote(quotes[rand_num].quote);
    setAuthor(quotes[rand_num].author);
    setColor(colors[rand_num]);
  }

Note that it will generate a random value each time it is called and use the same rand_num value for each of the useState actions.请注意,每次调用它都会生成一个随机值,并为每个 useState 操作使用相同的 rand_num 值。 If you want each one to have its individual random number, you should use the Math.floor logic individually on each one (maybe extracting it into another method).如果您希望每个人都有自己的随机数,您应该在每个人上单独使用 Math.floor 逻辑(也许将其提取到另一种方法中)。

  const getRandomNum= () => Math.floor(Math.random()*quotes.length);
  
  const handleQuote = () => {
    setQuote(quotes[getRandomNum()].quote);
    setAuthor(quotes[getRandomNum()].author);
    setColor(colors[getRandomNum()]);
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM