Home > Blockchain >  React: Update conditional on state change?
React: Update conditional on state change?

Time:12-15

I thought this would be a very basic feature for react, but it doesn't seem to update my code when variable state changes, for example if isPlaying changes, the icon doesn't.

Example:

<button id="playButton" onClick={this.onPlayButtonClicked} className="bg-green-500 p-2 px-4 text-white rounded shadow">
{ this.isPlaying ?
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> :
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
}
</button>

onPlayButtonClicked definition:

onPlayButtonClicked = () => {
    if (!this.isPlaying) {
        this.start(0, Math.round(this.currentTime - 0.5));
        this.isPlaying = true;
    }
    else {
        this.isPlaying = false;
        this.stop();
    }
}

CodePudding user response:

Try adding isPlaying to the state and use it by this.state.isPlaying. The component will rerender when the state or props change.

CodePudding user response:

isPlaying is not state so it won't rerender and you won't see any change. instead you can use state to handle it

sth like this :

class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isPlaying:false};
  }

onPlayButtonClicked = () => {
    if (!this.state.isPlaying) {
        this.start(0, Math.round(this.currentTime - 0.5));
        this.setState({isPlaying : true});
    }
    else {
      this.setState({isPlaying : false});
        this.stop();
    }
}

and in jsx :

<button id="playButton" onClick={this.onPlayButtonClicked} className="bg-green-500 p-2 px-4 text-white rounded shadow">
{ this.state.isPlaying ?
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> :
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
}
</button>

CodePudding user response:

You have to put the variable isPlaying in state variable. Like

constructor() {
    super()
    this.state = {
      isPlaying: false
    }
  }

And then you can change the state by

this.setState({
   isPlaying:true
})

Then you can use this state in your code as

    { this.state.isPlaying ?
    <svg key={1} className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> :
    <svg key={2} className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
}

This will re-render the component and your changes will be displayed.

CodePudding user response:

set state using this.setState

onPlayButtonClicked = () => {
    if (!this.state.isPlaying) {
        this.start(0, Math.round(this.currentTime - 0.5));
        this.setState({ isPlaying: true})
    }
    else {
        this.setState({ isPlaying: false})
        this.stop();
    }
}

or use the functional updater, if you have other state

   onPlayButtonClicked = () => {
        if (!this.state.isPlaying) {
            this.start(0, Math.round(this.currentTime - 0.5));
           this.setState((state, props) => ({ // get latest state and props
                   ...state, // included existing state
                  isPlaying: true //updated only what is needed
           }));
        }
        else {
             this.setState((state, props) => ({
                   ...state,
                  isPlaying: false
             }));
            this.stop();
        }
    }
  • Related