Source:  Twitter logo

How to change the button text when someone click on?

Code:

<Button disabled={this.state.disabled}
    type="primary"
    htmlType="submit"
    style={{
      background: '#ff9700',
      fontWeight: 'bold',
      border: 'none',
      float: 'center',
    }}
    loading={this.state.loading}
    onClick={this.enterLoading}
    value="Next"
    id="buttontext"
    onClick="changeText()"
>
    Next 
</Button>

Mayank is correct.

Create a variable called "text" (or whatever you choose) and put that instead of "Next".

state = {
  text: "Next"
}

changeText = (text) => {

  this.setState({ text }); 
} 
render() {
const { text } = this.state //destucture state
return (
  <Button 
     onClick={ () => { this.changeText("newtext")}  }> {text} </Button> )...etc

Note: this method will always change the text to "newtext" when you click. You can pass a variable there as well to make it more dynamic.

Hope this helps.

Update: Just saw Mayank comment. That code is essentially what I have. Just a tip you no longer need a constructor and you don't have to bind your methods anymore.

Updated: React Hooks

Same thing but with the useState hook. Instead of calling the state variable text, I am using buttonText to be more explicit. The updated version would look like:

import { useState } from 'React';

const [buttonText, setButtonText] = useState("Next"); //same as creating your state variable where "Next" is the default value for buttonText and setButtonText is the setter function for your state variable instead of setState

const changeText = (text) => setButtonText(text);

return (
  <Button onClick={() => changeText("newText")}>{buttonText}</Button>
)

You can omit the changeText function all together and have this:

return (
    <Button onClick={() => setButtonText("newText")}>{buttonText}</Button>
)

Updated: How to Add Set Timeout

Adding an update to answer a question in the comments: "If I wanted to use a setTimout to bring the button back to the previous text after 1 second where would I add that in?"

There are two ways that comes to mind: add the setTimeout to the changeText function or create an effect that depends on the buttonText.

change text

You can just pop the setTimeout right in this function.

Goes from this

const changeText = (text) => setButtonText(text);

to this

const initialState = "Next";
const [buttonText, setButtonText] = useState(initialState); //same as creating your state variable where "Next" is the default value for buttonText and setButtonText is the setter function for your state variable instead of setState

const changeText = (text) => {
  setButtonText(text);
  setTimeout(() => setButtonText(initialState), [1000])
}

We add the initialState variable as a const to keep track of the "previous text". Since, it should never change we could define it in all caps snake case like const INITIAL_STATE meh your choice.

useEffect

We still need to define that initialState variable, again so we can keep track of the original. Then we can create a useEffect which is a React hook that allows you to "hook" into changes of a variable (that's only a part of useEffect, just enough to get us going here).

We can break the effect down into two essential parts: the body or callback of the effect, what do we want to do when the effect runs and the dependency or what triggers the effect to run. In this case, our callback will be setTimeout and set the button text inside that timeout and our buttonText will trigger the effect.

Here's the effect:

useEffect(() => { 
  if(buttonText !== initialState){
    setTimeout(() => setButtonText(initialState), [1000])
  }
}, [buttonText])

Anytime the state variable buttonText changes this effect will run. We start at

buttonText = initialState // "Next"

the effect runs and checks the if. Since buttonText equals the initialState the conditions evaluates to false and we terminate the callback and the effect.

When the user clicks the button, changeText executes and sets the buttonText state which updates the variable triggering the effect. Now we run that if check again and this time it passes so we execute the setTimeout.

Inside the timeout we are setting state so the effect runs again and this time it fails because we just changed the state back to initialState.

I recommend throwing a debugger in there or some logs to follow the trail

Long winded explanation. Here's what the whole component would look like using the effect approach.

import React, { useState, useEffect } from "react";

const FancyButton = () => {
  const initialState = "Next";
  const [buttonText, setButtonText] = useState("Next"); //same as creating your state variable where "Next" is the default value for buttonText and setButtonText is the setter function for your state variable instead of setState

  // the effect
  useEffect(() => { 
    if(buttonText !== initialState){
      setTimeout(() => setButtonText(initialState), [1000])
    }
  }, [buttonText])

  const changeText = (text) => setButtonText(text);

  return (
    <button type="button" onClick={() => changeText("newText")}>{buttonText}</button>
  )
};

I added the type on the button because that's a good practice. And changed "Button" to "button". You can certainly have any component there you want, this works better for copying and pasting

26 users liked answer #0dislike answer #026
Bens Steves profile pic
Bens Steves

Where you wrote "Next", the button text, do this instead:

{this.state.disabled ? 'Disabled...' : 'Next'}

I this will display "Disabled..." when the state.disabled == true, and 'Next' when state.disabled == false.

0 users liked answer #1dislike answer #10
iateadonut profile pic
iateadonut

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).