quirks of input element in React - javascript

I'm new to React, sorry if my questions are trivial.
In React, if I write:
<input value="" />
then it will be an read-only field, and React forces me to add an onChange handler as:
<input value={this.state.greeting} onChange={this.handleChange} />
where handleChange() update component's state.greeting, therefore value gets updated too
Below are my questions:
Q1-why <input value="" /> is not read-only in plain html but read-only in React? How does React make it read-only
Q2-I found that if I write the code as below it also works, the input is not read-only
<input onChange={this.handleChange} />
and isn't that this approach better and more concise? because the internal value will get updated automatically in the browser, therefore we don't need to include an value attribute to read the data back from the state, which is unnecessary in most of times, so why I always see code like:
<input value={this.state.greeting} onChange={this.handleChange} />
Additional info:
some says it is controlled form elements that needs to have value attribute, but why we need to have a value attribute to read from the state? and when we type sth into the input, the onChange handler already updates the state, so it is still controlled.

To know how React makes your tags readonly, you will need to study the source-code that runs at your end and/or view the generated HTML. If still unsure about it, then you might want to send your first question to the authors of the tool.
The state is not on the server, unless you are polling or doing something of the like. It's in your browser as well. The value property specifies the initial value of your HTML element, that is, before you do anything your tag will have a value. In your case, your tag is controlled by React, but you need to initialize it. Benefits:
you will have the initial value
you will have a more readable code
your code will be written in the React-way, so you will not need to worry of unpleasant surprises

Related

Is it safe to use "readonly" elements in the form of ejs template?

I would like to know if any script with readonly elements is editable through bypassing. Im practicing an ejs template where I used the below script. People suggested me not to go with this action and mentioned it might not be secure.
For instance;
<input
type="text"
id="name"
name="name"
class="form-control"
value=<%= name %>
readonly/>
the name in the value will be the default value from the database. Is it possible for any malicious actors to edit the name even if it is non-editable? or if I use disabled elements, How could I make the value posted to the database?. I would like to know If there is any work around.
Could you please advice?
Thanks.
Yes, if you send values directly from this input, user can delete the readonly part and change the value. This can lead to undesirable results.
1. You can create a short-term Session[] for the value you want to send.
2. You can call it from where that you want to post it. (So there will be no link between the input field and the value you call there. The İnput field will only be used for view. You can also delete it or change readonly to disabled if you want.
my point of view 2>1.
You need to check value on the backend/server side too. You can't know if attacker is submitting value via your form or specially crafted request.

Where does Blazor store form data?

Interestingly, some input elements of Blazor Forms don't have the data stored in HTML as value (attribute) of the input-field. The fields doesn't even have a value attribute!
When I inspect and use 'Store as global object' functionality in chrome and check the value of the element in console (temp1.value), I can see the value.
I'm wondering where this value is being stored in the browser.
The value attribute is not set by changing the DOM's .value property.
Consider the following minimal example:
<input id=time>
<script>setInterval("time.value = new Date()", 1000);</script>
<input type=button onclick=alert(time.value) value=read>
You can inspect the clock and see that there's never a value attribute, yet the input's value property can be both setted and getted by script.
Thus, the value of the form input in your question can come from almost anywhere. It's likely embedded deep inside the other library support code that makes it easy to shuttle data back and forth, but that's speculation on my part. It's a JS variable of some sort, that much we know. The main thing is that attributes are not needed when making heavy use of JS.

Angular template variable reference

Here is a weird problem in Angular:
<input #pin1 type="password">
<p>You entered: {{pin1.value}}</p>
If you type something in <input>, the <p>'s content will not change which means pin1.value does not have value, does it mean the variable reference #pin1 does not work?
On the other hand, if we add a function to pass the reference, it will work.
<input #pin2 type="password" (input)="test(pin2)">
<p>You entered: {{pin2.value}}</p>
where test=function(x){console.log(x);}
For this <input>, if we type something, the the <p>'s content will change to corresponding text which implies #pin2 works.
So, the question is, in Angular, why we must use function to pass variable reference firstly then we can use it, why we cannot directly use variable reference.
Firstly, that is not how binding works.
What you did is creating a reference to input Dom object. At the time of the creation, the value of that Dom element (input) was empty. hence no value showing in your <p> tag.
if you want to see the value as you type then you are looking for a 2 way binding like so
<input [(ngModel)]="pin" type="password">
<p>You entered: {{pin}}</p>
Assuming that pin is declared in your ts file.
As to why the value was updating when you introduces a function, the answer is because Angular will be calling that function test(pin2) whenever you type something into that input which results in running a detect change on the model.
Long story short, Angular is a Model driven framework, if you need a value, you shouldn't need to get the DOM element to get the value from there.
I may get an ambiguous answer, it may be related to event binding, which means "view-to-source", if we didn't bind any event, the view (user interaction) cannot pass data to source (the component class), so variable reference may not work, but there are still some question like the template references should not be related to source side, since such variables aren't member/properties of component class.
it is so werired behaviour in angular
this code not working
<input #inputval type="text" />
<app-newcomp [testValue]="inputva.value"></app-newcomp>
but if you add "input" event to the input element then it will work
<input #inputval type="text" (input)="someFunctionInTs($event)" />
<app-newcomp [testValue]="inputva.value"></app-newcomp>

Correct way to set checkbox default state using JSX

If HTML5 specifies that there is no value for the "checked" attribute that is reliably interpreted as the checkbox being unchecked*, is the behavior of the following JSX code potentially inconsistent between browsers? (It seems to work as expected for me in Chrome and IE.)
<input type="checkbox" checked={node.props.checked} />
If so, what is the standard way to accomplish this, considering that the following JSX is invalid?
<input type="checkbox" {node.props.checked? "checked" : ""} />
What values for checked and selected are false?
You will need to conditionally add the entire checked attribute, not just the value of the attribute. That way, if you don't add the attribute at all, you will reliably get an unchecked checkbox.
If you are using ReactJS, then according to this answer:
React is intelligent enough to omit the attribute if the value you
pass to it is not truthy.

how are read-only fields implemented in React?

I put together this SSCCE to test read-only fields in forms created using ReactJS versus plain HTML forms and fields (also in jsfiddle):
<!doctype html>
<html>
<head>
<title>comparing ReactJS and simple HTML forms</title>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react.js"></script>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react-dom.js"></script>
</head>
<body>
<div>
<h3>HTML form</h3>
<form>
<input type='text' value='your name'/>
</form>
</div>
<div>
<h3>form created with ReactJS</h3>
<div id='reactForm'>
</div>
</div>
<script type='text/javascript'>
var rce = React.createElement.bind(React);
var SillyReactForm = React.createClass({
render: function() {
return rce('form', {}
, rce('input', { type: 'text', value:'your name'}));
}});
var form = rce(SillyReactForm, {});
ReactDOM.render(form, document.getElementById('reactForm'));
</script>
</body>
</html>
Sure enough, the field created with ReactJS is read-only and in fact I see this message in the console as well:
Warning: Failed form propType: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
My question is how is this enforced by ReactJS as, examining the DOM elements I see no essential difference between the plain HTML form and the ReactJS-generated one:
Is ReactJS executing some behind-the-scenes JavaScript that sets that field to effectively read-only? And if so, how can I discover this kind of logic that's attached to my DOM elements? Doesn't this run counter to the idea that ReactJS is a library and not a framework (and as such more transparent and easier to reason about?)
That warning isn't telling you that React is forcing the input to be readonly. It's telling you that React isn't. You'll end up with a mutable input representing immutable state. The user will be able to make changes to the input, but as soon as a re-render is triggered, those changes will be lost as the input is regenerated from the application state.
That's why React is telling you to add either the readOnly or onChange attribute. Either make the input immutable to match up with the state, or make the state mutable to match up with the input.
I haven't used defaultValue before, but I imagine it works by automatically hooking up an onChange event to some state behind the scenes. I think React probably also does the same if the value attribute is omitted, but does not do this if the value field is present, so as not to conflict with any state binding in the component, and instead throws this warning.

Categories