Why using value for input in react - reactjs

<input value={name.firstName} onChange={e => setName({firstName : e.target.value})} />
Even if we remove the value and use this code:
<input onChange={e => setName({firstName : e.target.value})} />
The app still works. What is the difference?
Second question, Do you think the hooks will be used as default for React to use? Will context api be replacement for redux in close future?

It's better to use value attribute, because if some error is thrown while setting a value, user will see it. For example, if value stops being stored in a state, the input will stop too. If you don't use value tag, input won't stop in that case.
NO. In react docs, we read "We intend for Hooks to cover all existing use cases for classes, but we will keep supporting class components for the foreseeable future. At Facebook, we have tens of thousands of components written as classes, and we have absolutely no plans to rewrite them. Instead, we are starting to use Hooks in the new code side by side with classes."
ContextAPI won't replace redux because of few big reasons. You don't have time travel debugger or configurable middleware.
Also you can read this article

Related

Reactjs Antd library and google maps Places

My team and I have been using Antd a react component library. I was asked to connect google.map's Places library to an input field so we can get an easy address drop-down list.
The problem is the Antd's input component is wrapped up under the hood. So when I click on an address from google.maps Places menu it appears in the input field for a milli sec then disappears.
I tried all the event.preventDefault(), event.stopPropoagtion(). Is there any trick to combining google.maps places returned data with a well nested react-ui component?
(too long for comment)
I have the exact same problem.
I'm using NextJS with functional component and #react-google-maps/api library.
The workaround I use: simple <input> element combined with the right CSS class to make it look like the Antd <Input>.
Like this:
<LoadScript
googleMapsApiKey={process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY}
libraries={libraries}
>
<Autocomplete
onLoad={(autocomplete) => setAutocomplete(autocomplete)}
onPlaceChanged={onPlaceChanged}
restrictions={{ country: "fr" }}
fields={['geometry.location', 'formatted_address']}
>
<input
type="text"
placeholder="Enter your address"
className="ant-input"
/>
</Autocomplete>
</LoadScript>
This way, when clicking on an address from Places menu, its value stays in the input field.
If anyone has a better and less hacky solution, I'm looking for one!
This is a very simple matter of state management. It sounds like the google-places input field was working correctly or it wouldn't have shown up at all. If your input field is connected to let's say Reactjs then you will need to add the google-places response data to your state-management and it should stop disappearing. This happens a lot when companies use custom state-management systems.

React, Reactstrap - Input vs input, form-control class prevents values from submitting, returns undefined

I am working on an basic React CRUD App and I came across a strange issue.
Using Reactstrap Input Component or the bootstrap class="form-control" the input values are undefined onSubmit.
If I leave the elements as a standard html input the values submit just fine?
I cannot figure out why this is happening.
I put together this demo that illustrates the issue.
Code Sandbox Snippet <- Live Demo
On the AddName.js file I have one Input and one input on submit you can see that the first name submits but the description does not.
<FormGroup>
<input
placeholder="First Name"
ref={nameInput => (this.nameInput = nameInput)}
/>
</FormGroup>
<FormGroup>
<Input
placeholder="Description"
ref={descriptionInput => (this.descriptionInput = descriptionInput)}
/>
</FormGroup>
Can anyone explain why this is happening? Is it possible how I have the refs on the inputs?
Before utilizing 3rd party packages, you should read into using Controlled Components strictly through React. Then, once you understand the flow, incorporate the packages.
I've rewritten your project to include all of the above, as well as written notes describing what I changed and why. There are also a few tricks and shortcuts I've used to simplify the code, such as: setState callback, ES6 Object Deconstruction and Fat Arrow Functions.
Working example: https://codesandbox.io/s/l9m0vor4wq
You should only need to use refs for obtaining a DOM element or a class instance for UI manipulation, instead of obtaining a data value. For example, utilizing a ref to draw attention to a DOM element via using its focus() method or removing attention from it via its blur() method. In your case, we would only use the synthetic event instead of a ref.
On a side note, be careful about using the name as a key in <PersonCard/>, because multiple users can share the same name value. This will cause React to complain that two keys are the same, and cause issues if you ever try to remove, resort, or filter the names list. To keep it simple, I instead used the key provided by the map function. While this approach works, it's not the best solution. Ideally, each person should have an id property with a UUID. This ensures all of your keys will be unique.

react willReceiveProps workaround for external library

I'm using a react datepicker component that can be found here. The component is pretty great except for what appears to be an oversight: it does not implement willReceiveProps.
To expound, I create the datpicker as below:
<DateField
dateFormat= { dateFormat}
forceValidDate={true}
defaultValue={startDate || ''}
onChange={this.handleChange.bind(null, 'start_date')}
id="start"
>
<DatePicker
navigation={true}
locale="en"
forceValidDate={true}
highlightWeekends={true}
highlightToday={true}
weekNumbers={true}
weekStartDay={0}
/>
</DateField>
Note above that there is a prop defaultValue which I pass startDate. Now, startDate can and does change for reasons that are sometimes external to the component. That value is passed during a new render() action as per usual. According to react philosophy this shouldn't be a problem.
However, it appears to me as if the value from defaultValue is only ever read once inside DateField. It is read as this.props.defaultValue. Anyone who has ever built a component relying on props should quickly recognize this is a problem. It means that when the prop is changed the new value will not be used.
Because this is a library, I cannot simply implement willReceiveProps. Does anyone know of a good workaround to get this component to either completely reset on a render or some other strategy to deal with what seems to be a big design problem?
They follow the same standards as the <input> component. defaultValue is read only once but there is also value that can be set externally. There is no need for them to use willReceiveProps.
In short, use value instead of defaultValue.
See Uncontrolled Components in React
PS: I am looking a bit into the code and it seems there are also properties text and date apart from value. Since the code (and documentation) has been removed from github, I won't inspect what is the difference between those props.

React client side validation with material-ui component

Some material-ui components have errorText as a prop which we can use to show errors, But, doing that in react become lot complex if my form has large number of field components.
Please suggest the best way to handle client-side validation with material-ui comonents.
I think your issue is that you have to manage a lot with state/store. In react validation is complex because of one-way binding.
This library https://github.com/vishalvisd/react-validator is one which I found that supports material-ui component validation. Though in general you may use this to validate any component.
I would suggest using some HoC (Higher-order Component) approach. I tested many solutions for form validation in React JS, the one that I always choose is: react-validation-mixin. Take a look at this example.
Example of the standard input:
<input
type='text'
placeholder='Username'
value={this.props.username}
onChange={this.onChange('username')}
onBlur={this.props.handleValidation('username')}
/>
In this example value of that input comes from props (example with Flux implementation) and that's probably what you aim for too (lots of inputs).
onChange will need to handle value change so that this.props.username gets updated too and onBlur will trigger validation check (so that the error will show up once user leaves the input).
In order to get the error message, use: this.props.getValidationMessages('username')
It's a universal solution and you can use it in different libs. But taking TextField from material-ui, as you asked:
<TextField
floatingLabelText="Username"
value={this.props.username}
errorText={this.props.getValidationMessages('username')}
onChange={this.onChange('username')}
onBlur={this.props.handleValidation('username')}
...
/>
Remember to use HoC with your component: export default validation(strategy)(UserLogin) That way, you will get all the necessary helper methods in props.
If you are using Redux in React project, redux-form give you a simple way to implement form validation.
Check this out: http://redux-form.com/6.4.3/examples/syncValidation/

Alternative to "mostly legacy" ref String Attribute?

I was a bit surprised when I read the updated React docs about refs. While their examples on the React front page still use this.refs.textarea, they later "recommend" to not use this approach anymore.
But what's the alternative? I find too long inline code confusing and calling a function instead, like {() => this.initChartLibrary() } (the () => is required to not lose context to this) requires to build a method that gives the wrong impression of that it can be reused.
In other words, I'd still like to use the String way. But since I fear they'll deprecate it, I was wondering, if there are any other approaches?
As far as I'm aware the main alternative to ref strings is in fact the ES6 style callback function.
So:
<textarea ref="myTextArea">
...
</textarea>
// Where refs are then accessed by `this.refs.myTextArea` to perform any operations
Becomes, in a basic form:
<textarea ref={ (ref) => this.myTextArea = ref }>
...
</textarea>
// Where refs are then accessed by `this.myTextArea`
This can be pretty powerful because the ref attribute in React automatically receives the referenced component as a parameter, which allows us to immediately implement our callback operations on it if we'd like. This can be used in a simple form, as above, to assign that reference to this.myTextArea, or as you've probably noticed in the docs, you can be a bit more direct and do things like:
<input
ref = {(input) =>
{ if (input != null) {input.focus()} }
} />
That being said, although this sometimes means you can express your code in the fewest number of lines, it definitely sacrifices readability. If you are just looking to save a reference to the component for use in an event handler (as is very commonly the case) using a ref string is honestly still the cleanest way to do so.
I really wouldn't anticipate them to be deprecated without warning, as they are used pretty heavily in React & remain convenient, but if they ever are your best bet would be a straightforward refactor with a simple (ref) => this.myRef = ref then accessing your refs by this.myRef.

Resources