useSignIn
Format: options => [state, signIn]
This hook returns a set of utilities for building a sign in form. It deals with form errors, form state and the Croods requests for you. It also returns the function to send all this data to the backend.
Returned values
const [{
formProps, // it contains props for the <form> element
passwordProps, // it contains props for the password <input> element
emailProps, // it contains props for the email <input> element
fields // it contains props for the other form fields
formState, // an object that contains input values, errors, and other info
signingIn, // true when executing the request
error, // error string in the request
},
signIn, // executes the sign in request
] = useSignIn()
Recommended configuration
It is important that you provide an afterSuccess with a plan to when the signIn succeeds. For instance:
const tuple = useSignIn({
afterSuccess: () => navigate('/dashboard'),
})
Other than all the Croods configuration you already know, you can also set your storage method and storageKey, because Croods-auth will use those values to save the headers on your localStorage.
import { AsyncStorage } from 'react-native'
const tuple = useSignIn({
afterSuccess: () => navigate('/'),
storage: AsyncStorage,
storageKey: 'mySp3ci4lK3y',
})
If you leave it as is, Croods-auth will use the defaults.
Usage samples
We are assuming a trivial input component on all examples below.
Build a simple sign in form
The formProps already has everything you need for when you submit the form. That means a basic button inside the form will be enough to dispatch the Croods request.
And the emailProps and passwordProps will take care of storing the form state and sending it when the form submits.
const [{
signingIn, formProps, emailProps, passwordProps,
}] = useSignIn({
afterSuccess: () => navigate(`/`),
})
const text = signingIn ? 'Signing in...' : 'Sign in'
return (
<form {...formProps}>
<h2>Sign In</h2>
<Input {...emailProps} />
<Input {...passwordProps} />
<button type="submit" className="btn">
{text}
</button>
</form>
)
Adding extra fields on the sign in form
As we are using react-use-form-state internally, you can add more fields usign its API.
const [{ formProps, emailProps, passwordProps, fields, fieldError }] = useSignIn()
return (
<form {...formProps}>
<h2>Sign In</h2>
<Input {...fields.text('fullName')} error={fieldError('fullName')} />
<Input {...emailProps} />
<Input {...passwordProps} />
<input {...fields.checkbox('terms')} />
<button type="submit" className="btn">
Sign in
</button>
</form>
)
A convenience method
We also provide fieldProps to create another fields with validation and have the error feedback built in.
It has the following format: fieldProps(type, name, validations). Where type is the input type, like 'email'/'text'/'number'. name will be the name of the input to be accessible in the formState. The third parameter validations is an array of functions that follows the redux-form-validators format, which is: (value, allFormValues) => string | undefined.
import words from 'lodash/words'
const minWords = length => value => words(value).length < length
? `Field must have at least ${length} words`
: undefined
const presence = value => value ? undefined : 'Field must have a value'
const [{ formProps, emailProps, passwordProps, fieldProps }] = useSignIn()
return (
<form {...formProps}>
<h2>Sign In</h2>
<Input {...fieldProps('text', 'fullName', [presence, minWords(2)])} />
<Input {...emailProps} />
<Input {...passwordProps} />
<input {...fields.checkbox('terms')} />
<button type="submit" className="btn">
Sign in
</button>
</form>
)
Showing errors
The fields will already receive the error string prop through emailProps, fieldProps, etc. But you can also show the errors comming from the API with the error value like so:
const [{ error, formProps, emailProps, passwordProps }] = useSignIn()
return (
<form {...formProps}>
<h2>Sign In</h2>
<Input {...emailProps} />
<Input {...passwordProps} />
{error && <span style={{ color: 'red' }}>{error}</span>}
<button type="submit" className="btn">
Sign in
</button>
</form>
)
Working with the formState
You can use formState and isFormValid to have access to the form state like so:
const [{
formState, formProps, isFormValid, emailProps, passwordProps,
}] = useSignIn()
return (
<form {...formProps} className={isFormValid ? 'valid' : 'invalid'}>
<h2>Sign In as: {formState.values.email}</h2>
<Input {...emailProps} />
<Input {...passwordProps} />
<button type="submit" className="btn">Sign in</button>
</form>
)
Using the received function
const [, signIn] = useSignIn()
return (
<button onClick={() =>
signIn({ email: 'john@doe.com', password: 'S3cr3t' })
}>
Sign in as John
</button>
)