Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

08 – Built in React APIs #10

Merged
merged 4 commits into from
Jun 14, 2022
Merged

08 – Built in React APIs #10

merged 4 commits into from
Jun 14, 2022

Conversation

lucasconstantino
Copy link
Contributor

@lucasconstantino lucasconstantino commented Jun 13, 2022

See Lesson 08: Built in React APIs wiki page for a full lesson wrap-up.

@vercel
Copy link

vercel bot commented Jun 13, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
frontend-academy-2022 ✅ Ready (Inspect) Visit Preview Jun 13, 2022 at 9:32PM (UTC)

Comment on lines +17 to +29
const validators = {
email: (value: string) => {
if (typeof value !== 'string') return 'Invalid e-mail value type'
if (!value) return 'E-mail is required'
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/u.test(value)) return 'Invalid e-mail'
},

password: (value: string) => {
if (typeof value !== 'string') return 'Invalid password value type'
if (!value) return 'Password is required'
},
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you may be confused about a couple of things:

1. Why an object?
We could, in theory, make each of these functions as top-level variables. But, having them declared as properties of an object gives us a couple of benefits:

  1. Simplified naming, as "email" is too generic, and "emailValidator" is not as simple anymore.
  2. validators becomes a map, which allow use to:
    1. Dynamically access a validator (e.g.: validators[inputName](inputValue))
    2. Iterate over validators

2. Why outside the component?
Generally speaking, anything that isn't dependent on props or state should live outside of the render cycle. This ensures, for instance, that these values never change, and thus memoization just becomes easier without the need of useMemo or useCallback all around. Besides that, you get better testability and overall simplification of the context where these assets are used.

3. Why the IFs and the undefined return
It's a common and generally nice pattern for value validators to return either a string explaining the failure, or undefined representing no issue is found. This way, any check on the validation result becomes as simple as this:

if (validator.email(value)) { /* handle error */ }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty clever! Damn, I wish I'd come up with this :D... With a combination of if statements it's super readable.

event.preventDefault()
setTimeout(() => {
// Mocking to represent login submit outcome.
const shouldFail = Math.random() < 0.5
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a temporary "hack" for us to easily try our form with multiple possible outcomes: some times it will randomly fail, some times it will succeed. You can easily click a couple of times on submit to see both UI states :)

Comment on lines +100 to +103
onChange={(e) => {
setEmailError(null)
setEmail(e.target.value)
}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are validating only on submit (which sucks, by the way, but we'll fix in the future), the best possible UX we could figure here is to ensure we clean any validation errors when the user modifies the input.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can imagine some kind of "debounce(500ms)" type of utility would be the best UX (users get informed even before they tab out), but I wonder why did you decide not to use onBlur property, isn't that a tiny bit better than validating on submit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct. Only then you’ll also have to validate on submit anyway. And suddenly you are repeating logic all around, doing very hard to read and imperative code.

You can check #11 on a more complete form state handling logic :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants