using innerHTML with React
Every time you change the state react calls the render function again, which means that if you wrote:
<div id ="display">{this.state.string}</div>
when you call clearingState function react will detect you changed the state and will render again your component and the statement {this.state.string} will be replaced for the new state value.
So, what is happening is: you are changing the state every time you call the createString function and then react calls the render function again to reflect the new state; then the user press the "=" operator and the getResult function is called and you manually changes the content of your display div; if the user press the "C" button the state is again updated and react calls render again to reflect the new state.
Another thing, is that you should not change the innerHTML property of your div manually. Instead, let react taking care of reflecting the state of your component. So, you should do this.setState({string: updatedResult}) and not worry about innerHTML.
Related videos on Youtube
Vera
Updated on June 04, 2022Comments
-
Vera almost 2 years
I've made a mini calculator using
React
.It works, but I'm not sure I understand why. Could someone point me towards the concept that I'm not fully grasping here.
My code's below.
Here's what I expected: After the first operation (first time the
getResult
function is executed) I expected to have to write a conditional in theclearingState
function to reset theinnerHTML
of<div id="display"
to{this.state.string}
as thegetResult
function sets it to theupdateResult
variable. Yet, it works without me having to do this adjustment. I don't understand why.Thanks in advance..
<script type="text/babel"> var Calculator = React.createClass({ createString: function(event){ var previousState = this.state.string; var target = event.target; var number = target.innerHTML; var newState = previousState+number; this.setState({string: newState}); }, clearingState: function(event){ var newState = ""; this.setState({string: newState}); }, getResult: function(){ var stringResult = this.state.string; var updateResult = eval(stringResult); return document.getElementById("display").innerHTML = updateResult; }, getInitialState: function(){ return ({ string: "" }) }, render: function(){ return ( <div> <div id ="display">{this.state.string}</div> <div id="main"> <div className="key zero" onClick={this.createString}>0</div> <div className="key one" onClick={this.createString}>1</div> <div className="key two" onClick={this.createString}>2</div> <div className="key three" onClick={this.createString}>3</div> <div className="key four" onClick={this.createString}>4</div> <div className="key five" onClick={this.createString}>5</div> <div className="key six" onClick={this.createString}>6</div> <div className="key seven" onClick={this.createString}>7</div> <div className="key eight" onClick={this.createString}>8</div> <div className="key nine" onClick={this.createString}>9</div> <div className="key d" onClick={this.createString}>.</div> <div className="key C" onClick={this.clearingState}>C</div> </div> <div id="operators"> <div className="key mp" onClick={this.createString}>*</div> <div className="key dv" onClick={this.createString}>/</div> <div className="key ad" onClick={this.createString}>+</div> <div className="key sb" onClick={this.createString}>-</div> <div className="key eq" onClick={this.getResult}>=</div> </div> </div> ); } }); ReactDOM.render( <Calculator/>, document.getElementById('calculator') )
-
azium over 8 yearsEvery time you call
setState
, React automatically callsrender
again (with the new state). Out of curiosity, are you using the React official docs as a guide? -
azium over 8 yearsYou should never need to manually update
innerHTML
in a React application. You should only callsetState
and let React handle updating the DOM for you. -
Vera over 8 years@azium, thank you for your explanation. I replaced this:
return document.getElementById("display").innerHTML = updateResult;
with this instead:this.setState({string: updateResult});
And you're right about setState and rendering. I still don't understand though, why that previous code worked.. as the way it was written before I really thought I was overriding the {this.state.string} with my updateResult variable. Sorry that I'm being slow to catch up on this... And yes, I am reading the docs, though not always understanding :)
-
-
Vera over 8 yearsThank you. I guess I wasn't getting it because I thought I was modifying what's in the render function with my call to getResult, which is a silly thought now that I think of it more. Thanks a lot to the both of you @azium as well :)