Different behavior compared to native react.js: state sudden reset
See original GitHub issueHi. I tried to translate this simple code into scalajs-react:
/* Javascript */
// Just a plain Input object which saves user's input as a state
var Input = React.createClass({
getInitialState: function() { return { value: '' } },
onChanged: function(e) {
this.setState({ value: e.target.value });
},
render: function() {
// <input type="text" value={this.state.value} onChange={this.onChanged} />
return React.createElement("input", {type: "text", value: this.state.value, onChange: this.onChanged});
}
});
// Displays a number and an <Input> next to it
var TestCounter = React.createClass({
render: function() {
// <div>
// <span>{this.props.counter}</span>
// <Input />
// </div>
return React.createElement("div", {},
React.createElement("span", {}, this.props.counter),
React.createElement(Input)
);
}
});
// Launch the counter
var cnt = 0;
setInterval(function(){
ReactDOM.render(React.createElement(TestCounter, {counter: cnt}), domNode);
cnt ++;
}, 1000);
And the result:
/* Scala */
// Just a plain Input object which saves user's input as a state
class InputBackend($: BackendScope[Unit, String]) {
def onChanged(e: ReactEventI): Callback ={
$.modState((_) => {e.target.value} );
}
def render() = {
<.input (
^.`type` := "text",
^.value := $.state.runNow(),
^.onChange ==> onChanged
);
}
}
// Displays a number and an <Input> next to it
class TextCounterBackend($: BackendScope[Int, Unit]) {
def render() = {
val Child = ReactComponentB[Unit]("Input")
.initialState("this string wipes out any change in the input")
.renderBackend[InputBackend]
.build
<.div(
<.span($.props.runNow()),
Child(Unit)
);
}
}
var cnt = 0;
// Launch the counter
@JSExport
override def main(): Unit = {
setInterval(1000) {
ReactDOM.render(
ReactComponentB[Int]("TextCounter")
.renderBackend[TextCounterBackend]
.build(cnt),
dom.document.getElementById("test_javascript_scala")
);
cnt += 1;
};
}
However, the result in the browser behaves differently from the original one:
- in the first case (javascript) the counter is ticking and I can seamlessly modify the value of the input, the change is preserved from tick to tick;
- in the 2nd case (scalajs-react) the counter is ticking, but any change I introduce is dropped to the initial one on each next tick.
Am I doing something wrong here?
Issue Analytics
- State:
- Created 8 years ago
- Comments:6 (3 by maintainers)
Top Results From Across the Web
Preserving and Resetting State - React Docs Beta
State is isolated between components. React keeps track of which state belongs to which component based on their place in the UI tree....
Read more >Avoid parent component resetting child components state
Each item should have a unique and stable key, otherwise React will unmount it and re-render it, causing the state resetting you experience....
Read more >React Hooks cheat sheet: Best practices with examples
In this tutorial, we'll outline some React Hooks best practices and ... state value (not necessarily the initial state) and another function ...
Read more >How to Manage State in a React App – With Hooks, Redux ...
Hi! In this article we'll take a look at the many ways you can manage state in a React app. We'll start by...
Read more >5 Methods to Persisting State Between Page Reloads in React
One of the straightforward options is to use localStorage in the browser to persist the state. Let's take a look at an example....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@stillwaiting It was a case of #255.
While we’re here, there are a few small improvements to suggest.
You can change
to
and
to
They’re different (hi btw) in that unlike the JS version, in your Scala version you’re creating the component inside the tick-loop. Which means React keeps thinking it’s got new components each tick.
Move this:
to the top level, outside of the loop.
A common structure I use is to have an object with Props and/or State and/or Backend types defined inside, and a
val Component = ReactComponentB ... .build
so that everything pertaining to the component is all in one unit.Like: