Static forms don't give the user a lot of information about how to submit the form. We can use Reacts onChange
prop on an input to dynamically update the form; disabling and enabling the submit button on a condition. This allows for custom validation as the user makes changes to the input.
after we add <button disabled={Boolean(error)} type="submit">Submit</button>
, the alert(
error: ${error})
statement inside handleSubmit
will never execute. And can be removed.
after we add
<button disabled={Boolean(error)} type="submit">Submit</button>
, thealert(
error: ${error})
statement insidehandleSubmit
will never execute. And can be removed.
Agreed. I think this could be slightly confusing to people and might best be removed after adding the boolean
Hi Kent,
Why you return null
from getErrorMessage()
if the given param doesn't match any of above if
statements?
And why you use disabled=Boolean(error)
instead of disabled={error}
Thanks :)
Hi Konekoya!
I prefer explicitness. It helps future code readers know my intentions. If I didn't return anything, then it could be interpreted that the original coder hadn't considered that case. I also like to be explicit about my booleans, so rather than relying on truthiness/falsiness, I generally cast things to booleans with the Boolean
constructor.
I hope that's helpful.
Thoughts on returning an empty div element when there is no error?
error ? <div style={{color: 'red'}}>{error}</div> : <div/>
That way the Submit button doesn't jump up.
Bijoy, that'd be fine. You could also accomplish that with styling. But it really doesn't matter either way.
Isn't it bad UX to yell at people for having invalid input before they've even had a chance to type something? In the angular world, there's these values for a 'dirty' or 'pristine' form that we can use, is there a React equivalent?
You're correct Brendan, I would probably want to do more work here for a better user experience. React doesn't have support for things like dirty or pristine. You'll have to implement that yourself. You might consider using formik or react-final-form.
Okay cool. I guess this is one of those things where React is more of an 'ecosystem' of 3rd party libraries, for better or worse, and Angular is more of an opinionated framework.
<NameForm
getErrorMessage= {value => {
if (value.length < 3) {
...
Where does the value
come from here?
@Greg, That's provided by the caller (see references to this.props.getErrorMessage
).
Ah, now I see it. Thank you!
Hi Kent, why did you make getErrorMessage
a prop instead of a method inside <NameForm />
? Personal preference or is there an advantage to initializing this way?
It was just a way I could show the functionality without including the implementation details in the NameForm.
Is there any advantage in using
{error ? (
<div style={{color: 'red'}}>
{error}
</div>
) : null}
over
{error && (
<div style={{color: 'red'}}>
{error}
</div>
)}
As I said on twitter recently:
I make it a rule to prefer ternaries over &&
I've been burned by react rendering 0 instead of not rendering something because I did:
{users.length && users.map(/* stuff */)}
So I just avoid the problem altogether by using ternaries.
I've been burned by react rendering 0 instead of not rendering something because I did:
{users.length && users.map(/* stuff */)}
Why would this render 0? Is that a bug? Or is there something about map()
that I don't understand?
Try this in your console:
var users = []
console.log(users.length && users.map(() => {}))
You'll get the output is 0
In React, doing the above is effectively doing this:
<div>{0}</div>
It will render 0. This is because 0
is a falsey value so the right side of the &&
is not evaluated and the left side (0
) is used for the expression value.
Hey Kent,
When we initialize the components state and call getErrorMessage()
with an empty string, the length of value is 0 and the first if condition (value.length < 3)
seems to be met resulting in an error message being displayed on first render. I see one way this could be handled is to add another condition to getErrorMessage()
i.e. length === 0
or some other 'initializing condition' and return an empty string. Understanding that this example is for learning purposes and a production form may have a very different implementation I'm just interested to hear your thoughts on this and any other approaches you may have to handle this scenario...Thanks much.
Yup, the use cases vary and you have the flexibility of JavaScript to create the user experience that you need :)
I am seeing setState
method being used from last couple of lessons. is that the this.setState
comes with React.Component
? so you have to use class to use this method, any other implementation to use this method? any other methods like this that we should be knowing and useful?
There are other things available, but you don't typically use anything other than setState()
, props
, and state