Reputation: 15659
I am using these two nice react
form libraries (together with axios
):
react-bootstrap
andreact-hook-form
(seems to be the react form library on the up)There doesn't seem to be a definitive reference to getting the two to play nice? What is the basic recipe?
This question and this issue partly address the point but its all a bit occult.
(I've tried to answer this question myself below but please feel free to improve - especially if it demonstrated better use of these libraries working togethether)
Upvotes: 11
Views: 10143
Reputation: 15659
This example seems operational:
but it's just starting point!
import React from "react"
import {Form, Button, Card, Container, Row, Col, } from 'react-bootstrap'
import Server from "../Server.js"
import { JSONDisplayer } from "./Widgets"
import { useHistory } from "react-router-dom"
import { useForm, Controller } from 'react-hook-form'
import {display_errors} from '../Utilities.js'
function Signup() {
const history = useHistory()
const {setError, handleSubmit, control, reset, formState: {errors}, getValues
} = useForm()
const onSubmit = (data) => {
console.log('data', data)
return Server.post('/user/create/', data)
.then(result => {
console.log('login result', result)
history.push("/login")
})
.catch(error => {display_errors(error, getValues, setError)})
}
return (
<Container> <Row> <Col>
<Card><Card.Header>Create a new user</Card.Header><Card.Body>
<Form onSubmit={handleSubmit(onSubmit)} onReset={reset} >
<Form.Group className="mb-3" controlId="formUsername">
<Form.Label>User name</Form.Label>
<Controller control={control} name="username"
defaultValue=""
render={({ field: { onChange, onBlur, value, ref } }) => (
<Form.Control onChange={onChange} value={value} ref={ref}
isInvalid={errors.username}
placeholder="Enter user name" />)} />
<Form.Text className="text-muted">Login name</Form.Text>
<Form.Control.Feedback type="invalid">
{errors.username?.message}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3" controlId="formEmail">
<Form.Label>Email</Form.Label>
<Controller control={control} name="email"
defaultValue=""
render={({field: {onChange, onBlur, value, ref}}) => (
<Form.Control onChange={onChange} value={value} ref={ref} type="email"
isInvalid={errors.email}
placeholder="Enter email" />)} />
<Form.Text className="text-muted">We need a valid email address.</Form.Text>
<Form.Control.Feedback type="invalid">
{errors.email?.message}
</Form.Control.Feedback>
</Form.Group>
<Form.Group className="mb-3" controlId="password">
<Form.Label>Password</Form.Label>
<Controller control={control} name="password"
defaultValue=""
render={({ field: { onChange, onBlur, value, ref } }) => (
<Form.Control
onChange={onChange} value={value} ref={ref} type="password"
isInvalid={errors.password}
placeholder="Enter password" />
)} />
<Form.Text className="text-muted">Don't forget it!!</Form.Text>
<Form.Control.Feedback type="invalid">
{errors.password?.message}
</Form.Control.Feedback>
</Form.Group>
<Controller control={control}
render={({ field: { ref }, formState }) => (
<Button type="submit" disabled={formState.isSubmitting}
className="btn btn-primary">
{formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1" />}
Save
</Button>
)} />
</Form></Card.Body></Card>
</Col> </Row> </Container>
)
}
export default Signup
Generic axios
-> react-hook-form
error transcriber function:
// transcibe axios errors to react-hook-form
function display_errors(error, getValues, setError) {
const errs = error.response.data || []
var got_a_useful_message = false
// loop over all the fields and set error:
for (var field of Object.keys(getValues())) {
if (errs[field]) {
got_a_useful_message = true
setError(field, {
type: "server",
message: errs[field].join(' | ')})
}
}
if (!got_a_useful_message) {
alert('something has gone wrong')
}
}
export {display_errors}
Upvotes: 11