Reputation: 3535
So, I have the IssuesList
component, which is the list of issues that I get using ajax and github api, and DevStatus
component, which sort of wraps the list up and contains all the logic, triggers state changes by two radiobuttons and so on.
My problem: When I click on one of the radiobuttons, the DevStatus
component won't change state if the click was on the text inside the radiobutton. And when I click on the corners of the radiobuttons, the blue areas without text, the state changes perfectly.
Here's the structure of the radiobuttons:
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.CLOSED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Closed Issues
</label>
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.OPENED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Open Issues
</label>
</div>
Here's the codepen with the code and here's the full page view so you could better see and understand what I'm talking about.
Please, open the full page view and try to click on parts of the button that contain text and on ones that don't and you'll notice that as long as you click on parts without text - the state changes and if you click on text itself - the state doesn't change at all.
Could you please help me with that problem?
PS: removing onChange
from the input
element is not the solution.
If you go to DevTools and inspect the radiobutton element, you'll see that inside the label
tag there're input
and weird span
elements. The span
element is not in the code I wrote, did React automatically add that? For some reason, the onClick
event listener is not applied to those input
and span
elements.
I've tried to add click
event listener to the radiobutton in the console of dev tools and tried to figure out the target of the clicked element. When I click on the text - it is the span
element and when I click on place without text - it is the label
element and that's why the click event is not working.
Can my problem be solved using dangerouslySetInnerHTML
, so that it won't create the unnecessary span
?
Could you tell me please how to solve that?
Upvotes: 1
Views: 629
Reputation: 7045
React is creating a span because your text is not in any div. Also it would create a span if there was any white space (but in your case this is because there is no div around your text).
But the real problem here is the way you check your event. You need to check e.currentTarget instead of e.target
Then no need to use the ugly dangerouslysetinnerhtml!
Upvotes: 2
Reputation: 3535
React appeared to sometimes be adding span
tags around text, no matter if there are the free white-spaces or not. The span
s didn't allow the onClick
event to fire when they were clicked on.
So, to force React not to render the span
s, the dangerouslySetInnerHTML
may be used:
noSpanRender(text) {
return { __html: `<input type='radio' name='options' autoComplete='off'/>${text}` };
}
render() {
return (
<div className="dev-status-page col-centered">
<div className="graphs">
<h1 className="text-center page-header">
Our Recent Closed and Opened Issues from GitHub
</h1>
</div>
<div className="issues col-centered">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Closed Issues')} />
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Open Issues')} />
</div>
<IssuesList issues={this.state.issues} />
</div>
</div>
)
}
It was vital to avoid those span
elements inside the input
tag, so using dangerouslySetInnerHTML
finally helped.
Upvotes: 0