简体   繁体   中英

How to Change Button text in React using useState

I have a button with Text Click View Price . I am displaying Amount when button is clicked.

I want to change the button value to priceVar = "Reset Price"; which is not happening in my case. I am able to set value to 0.

How can I set button text to Reset Price again?

 const [price, setPrice] = useState(0);
  let priceVar = "Click View Price";
  const viewPrice = () => {
    if (price === 0) {
      setPrice(Math.floor(Math.random() * 100));
    } else {
      priceVar = "Reset Price"; --------------------> NOT WORKING
      setPrice(0);
    }
  };

  return (
    <article
      className="book"
      onMouseOver={() => {
        console.log(title);
      }}
    >
      <div>
        <button type="button" onClick={viewPrice()}>
          {priceVar}
        </button>
        <h3>${price}</h3>
      </div>
    </article>
  );

You can create useState hook for Button text as below

 const [priceVar, setpriceVar] = useState("Click View Price");

 const viewPrice = () => {
    if (price === 0) {
      setpriceVar("Click View Price");
      setPrice(Math.floor(Math.random() * 100));
    } else {
      setpriceVar("Reset Price");
      setPrice(0);
    }
  };

Your variable is not React State!

 import { useState } from "react"; let priceVar = "..."; // Try useState like with your price variable: const [priceVarNew, setPriceVarNew] = useState("Click View Price") // Then reference that state like your price with: {priceVar}, or change it accordingly with setState("Reset Price")

You can also make ternary for this one also. setPrice(price === 0? Math.floor(Math.random() * 100): 0);

You almost have it!

Your current code has this flow:

  • declare priceVar
  • declare function which does some stuff (including changing the button text variable as you want)
  • render component with a button that has an onclick which is your declared function

In React, renders(updates) to your components are triggered by props or state changing, and in this case, your button text is not something that is triggered by state directly. setPrice does trigger a re-render which is almost indirectly what you want, but because you declare the text at the top of your component, you're just asking your component to render the same text again, thus the lack of change.

There's a number of ways to achieve this. But in your case, it seems as if you want your button text to be Reset Price when your state variable price is equal to 0. So instead of using a priceVar you could simply check the price at the point where you want to decide your button text. Shown below:

    <button type="button" onClick={viewPrice()}>
      {price === 0 ? "Reset Price" : "Click view price"}
    </button>

There's ways in which you could clean this up or be more elegant, but the important thing here to note is that you're relying on some react state which is vital in scenarios like this where your component UI needs to change with different circumstances.

You're very close, you just need to understand that you can't create stateful values using let or const . That's why we have setters like useState , useRef , useReducer etc which hold on to their values across renders. A standard variable won't so won't work the way you might expect.

So, you could opt to create a new piece of state by replacing:

let priceVar = "Click View Price";

With:

const [priceVar, setPriceVar] = useState("Click View Price");

And update it accordingly.

Or, give this article a read to understand when you should derive state, instead of syncing it.

In your case, the line:

let priceVar = "Click View Price";

Would be replaced with:

const priceVar = price === 0 ? "Click View Price" : "Reset Price";

Check it out here.

Also as a side note, you're calling the viewPrice function as soon as the component renders, which isn't what you want to do. This makes sense because if you were to call a function in vanilla JavaScript, you'd follow the pattern: someFunction() and expect it to be called.

Instead, replace your onClick handlers with:

onClick={viewPrice}

Or:

onClick={() => viewPrice()}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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