1

I have an Alerts component which is responsible for rendering alerts from JSON supplied to it's props:

alert.js (cut down for brevity)

  createAlert(alerts) {
    return alerts.map(content => (
      <Col key={content.ID} s={12}>
        <div className="chip">
          <Icon className="alert">error_outline</Icon>
          <p>{content.Comment}</p>
          <span onClick={() => this.props.onRead(content.ID)}>
            <Icon className="closeAlert">close</Icon>
          </span>
        </div>
      </Col>
    ));
  }
  render() {
    let content = {};
    if (!this.props.content) {
      //Alerts are null so they are still loading.. show loader
      content = this.createLoader();
    } else if (!this.props.content.success){
      //Error getting alerts
      content = this.createAlertError(this.props.content.error);
    }
    else if (this.props.content.alerts.length === 0) {
      //Alert array is null, therefor no alerts
      content = this.createNoAlerts();
    } else {
      //Render Alerts
      content = this.createAlert(this.props.content.alerts);
    }
    return <div>{content}</div>;
  }
}

In the above snippit, you can see that if

this.props.alerts 

is an array with elements, then it will run

createAlert() 

which will create an array of React Components (in this case its just React-Materialize component which is just a <div></div>)

the part I am interested in is the span with the onClick event

<span onClick={() => this.props.onRead(content.ID)}>
  <Icon className="closeAlert">close</Icon>
</span>

This run an event from the parent component. The method that is run in the parent is as follows:

alertRead(id) {
  this.props.deleteAlert(id);
}

What I would like, is some way to add a spinning loader icon into the button on the click, in jQuery it would be:

$(button).on("click", function(){
  this.html("<i class='fa fa-spin fa-spinner'></i>");  //Spinner Icon
});

The question is, how do I edit the HTML of the button that is clicked on click?

1
  • Please edit your question to make it a little bit clear: the first sentence after the big snippet of code is not complete. If you clear it a little bit maybe I can help you out :) Commented Jan 24, 2018 at 13:15

1 Answer 1

2

No Redux version

I don't see any redux relation in the code so I will assume that you are not using it or not using it in this particular flow.

What you need to do is to add state to the Alert component and do two things in onClick handler:

() => { this.props.onRead(content.ID); this.setState({clicked: true});}

Of course you need to have state initialization with clicked: false. Second thing is to use this state in rendering:

{this.state.clicked && <Loader />}
{!this.state.clicked && <YourButton />}

So when clicked show loader when not clicked show button. Above code examples are only for showing you the right path.


Version assuming of Redux using.

If you are using redux then alert needs to have connection with the store like:

connect((state) => ({ isClicked: getIsButtonClicked(state)}), { dispatchClick })(AlertComponent)

And you need to dispatch click action after click ( it will set the store state responsible for that - clicked on true.

() => { this.props.onRead(content.ID); this.props.dispatchClick();}

Also finnaly you need to use this prop in rendering:

{this.props.isClicked && <Loader />}
{!this.props.isClicked && <YourButton />}

This solution will cover all instances of Alert component. I am not covering here the redux part.

Sign up to request clarification or add additional context in comments.

6 Comments

I am using redux, and just tagged it incase it was relevant. But for this particular component I am using props and the component state..
Even if you use redux then if this is statefull component this approach can be used. Of course the best would be connect this component to the store and do the same logic with button or loader but on the prop from the store.
I did consider using state, but the problem is that I have an Array of dynamically generated DIV's... There maybe upto 10 alerts on the page.
and all need to have spinner when clicked in one of them?
yes thats correct. but I think your first comment is right, I need to connect it to the store rather than this approach
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.