The biggest lies aboutThe biggest lies about
React HooksReact Hooks
fakiolasmarios@gmail.com
twitter.com/@fakiolinho - medium.com/@fakiolinho 1
Full-stack JavaScript lover, happy husband, proud father
Software Engineering Manager / Frontend Head at omilia.com
Fakiolas Marios
fakiolasmarios@gmail.com - twitter.com/@fakiolinho - medium.com/@fakiolinho
Workshops Tutor at 2hog.codes
2
React HooksReact Hooks
React 16.8 - 6/2/2019
3 . 1
React HooksReact Hooks
React 16.8 - 6/2/2019
3 . 2
React HooksReact Hooks
were created so we can winwere created so we can win
the fight against evil classesthe fight against evil classes
4 . 1
React HooksReact Hooks
were created so we can winwere created so we can win
the fight against evil classesthe fight against evil classes
4 . 2
React HooksReact Hooks
so why then?
5
React HooksReact Hooks
were created in order to re-use
logic without nesting deeper in
the components tree
...i am looking at you HOCs and render props
6
As an architect, you are asked to
design a brand new project
7
Your go-to technology is ReactJS
8
Specs indicate that lots of forms will
be implemented
9
You decide to go with
controlled components
10 . 1
class Form extends React.Component {
state = {
field: '',
};
handleSubmit = data => axios.post('/url', data);
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
value={this.state.field}
onChange={e => (
this.setState({ field: e.target.value })
)}
/>
</form>
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A class component is required
10 . 2
state = {
field: '',
};
<input
value={this.state.field}
onChange={e => (
this.setState({ field: e.target.value })
)}
class Form extends React.Component {1
2
3
4
5
handleSubmit = data => axios.post('/url', data);6
7
render() {8
return (9
<form onSubmit={this.handleSubmit}>10
11
12
13
14
15
/>16
</form>17
);18
}19
Because you need internal state
10 . 3
...and you ship it
11
...the project should support longer
forms with multiple fields
12
Who hates some old-fashioned
copy-paste right?
13 . 1
<form onSubmit={this.handleSubmit}>
<input
value={this.state.field1}
onChange={e => (
this.setState(prevState => ({
...prevState,
field1: e.target.value
}))
)}
/>
<input
value={this.state.field2}
onChange={e => (
this.setState(prevState => ({
...prevState,
field2: e.target.value
}))
)}
/>
...
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
13 . 2
...and you ship it
14
...the project should support
complex forms with different
types of fields
15
Copy and paste won't do the job this time
16
maybe we can create some re-usable
components and move faster
17
const Field = ({
name="field",
value="",
type="text",
onChange,
}) => (
<input
name={name}
type={type}
value={value}
onChange={onChange}
/>
);
1
2
3
4
5
6
7
8
9
10
11
12
13
Let's create our own Field component
18 . 1
class Form extends React.Component {
state = {
field: '',
};
handleChange = e => this.setState({
[e.target.name]: e.target.value,
});
handleSubmit = e => {
e.preventDefault();
axios.post('/url', this.state);
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<Field
name="field"
value={this.state.field}
onChange={this.handleChange}
/>
</form>
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Refactor our Form component
18 . 2
handleChange = e => this.setState(prevState => ({
...prevState,
[e.target.name]: e.target.value,
}));
<Field
name="field"
value={this.state.field}
onChange={this.handleChange}
/>
<Field.../>
class Form extends React.Component {1
state = {2
field: '',3
};4
5
6
7
8
9
10
handleSubmit = e => ...;11
12
render() {13
return (14
<form onSubmit={this.handleSubmit}>15
16
17
18
19
20
21
</form>22
);23
}24
}25
Field component can be re-used easily
18 . 3
What about forms logic?
It is not that re-usable
19 . 1
state = {
field: '',
};
handleChange = e => this.setState({
[e.target.name]: e.target.value,
});
handleSubmit = e => {
e.preventDefault();
axios.post('/url', this.state);
};
class Form extends React.Component {1
2
3
4
5
6
7
8
9
10
11
12
13
14
render() {15
return (16
<form onSubmit={this.handleSubmit}>17
<Field18
name="field"19
value={this.state.field}20
onChange={this.handleChange}21
/>22
</form>23
);24
}25
}26
Repeated logic across all forms
19 . 2
Let's provide a wrapper that will bring
this kind of logic anywhere we like
20
const Form = () => {
const initialValues = {
field: "",
};
const handleSubmit = data => axios.post('/url', data);
return (
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, onChange, onSubmit }) => (
<form onSubmit={onSubmit}>
<Field
value={values.field}
name="field"
onChange={onChange}
/>
</form>
)}
</FormHandler>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Let's use render props pattern
21 . 1
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, onChange, onSubmit }) => (
)}
</FormHandler>
const Form = () => {1
const initialValues = {2
field: "",3
};4
5
const handleSubmit = data => axios.post('/url', data);6
7
return (8
9
10
<form onSubmit={onSubmit}>11
<Field12
value={values.field}13
name="field"14
onChange={onChange}15
/>16
</form>17
18
19
);20
};21
Re-usable logic by using render props
21 . 2
<form onSubmit={onSubmit}>
value={values.field}
onChange={onChange}
const Form = () => {1
const initialValues = {2
field: "",3
};4
5
const handleSubmit = data => axios.post('/url', data);6
7
return (8
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>9
{({ values, onChange, onSubmit }) => (10
11
<Field12
13
name="field"14
15
/>16
</form>17
)}18
</FormHandler>19
);20
};21
Re-usable logic by using render props
21 . 3
export default class FormHandler extends React.Component {
state = this.props.initialValues;
handleChange = e => {
e.persist();
this.setState(prevState => ({
...prevState,
[e.target.name]: e.target.value
}));
};
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.state);
};
render() {
return this.props.children({
values: this.state,
onChange: this.handleChange,
onSubmit: this.handleSubmit
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Re-usable logic by using render props
21 . 4
Neat, our forms are looking good
22
...the project needs to provide a
confirmation step for all the forms that
have a destructive purpose
23
We need a confirmation step for
certain forms
24 . 1
Should we add a prop named
"shouldDoubleCheck"
to prevent forms submission at will?
<FormHandler
shouldDoubleCheck
initialValues={initialValues}
onSubmit={onSubmit}
>
...
</FormHandler>
1
2
3
4
5
6
7
24 . 2
handleSubmit = e => {
e.preventDefault();
if (this.props.shouldDoubleCheckout) {
const answer = window.confirm('Are you really sure about this?');
if (answer) {
this.props.onSubmit(this.state);
}
} else {
this.props.onSubmit(this.state);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
Check for "shouldDoubleCheck"
across all forms submissions
24 . 3
This logic will run across all forms right?
Only a few really will use it
25
We need another wrapper that will
introduce this confirmation logic
26
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, onChange, onSubmit }) => (
<DoubleCheckHandler onSubmit={onSubmit}>
{({ onSubmitWithDoubleCheck }) => (
<form onSubmit={onSubmitWithDoubleCheck}>
<Field
value={values.field}
name="field"
label="Field"
onChange={onChange}
/>
</form>
)}
</DoubleCheckHandler>
)}
</FormHandler>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Introduce "DoubleCheckHandler" wrapper
27 . 1
<DoubleCheckHandler onSubmit={onSubmit}>
{({ onSubmitWithDoubleCheck }) => (
<form onSubmit={onSubmitWithDoubleCheck}>
)}
</DoubleCheckHandler>
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>1
{({ values, onChange, onSubmit }) => (2
3
4
5
<Field6
value={values.field}7
name="field"8
label="Field"9
onChange={onChange}10
/>11
</form>12
13
14
)}15
</FormHandler>16
Introduce "DoubleCheckHandler" wrapper
27 . 2
const DoubleCheckHandler = ({ onSubmit, children }) => {
const handleSubmitWithDoubleCheck = e => {
e.preventDefault();
const answer = window.confirm("Are you really sure about this?");
if (answer) {
onSubmit(e);
}
};
return children({
onSubmitWithDoubleCheck: handleSubmitWithDoubleCheck
});
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
No "shouldDoubleCheck" prop is
needed in DoubleCheckHandler
27 . 3
Neat, our forms are looking good
Let's share all this effort with the
teammates
28
No-one seems to be excited
29
"This is not that readable. How are we
going to maintain these components?"
30 . 1
<FormHandler initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, onChange, onSubmit }) => (
<DoubleCheckHandler onSubmit={onSubmit}>
{({ onSubmitWithDoubleCheck }) => (
...
)}
</DoubleCheckHandler>
)}
</FormHandler>
1
2
3
4
5
6
7
8
9
30 . 2
"What about all these wrapping components?
Components tree seems pretty ugly"
31 . 1
31 . 2
"What about testing? How deep we should
go to find and tweak a Field?"
32 . 1
We need to use full mount with enzyme
or many dives with shallow testing
32 . 2
Obviously this solution isn't that cool
33
Time to jump 1 year ahead and reach
Hooks era
34 . 1
const Form = () => {
const initialValues = {
field: '',
};
const handleSubmit = data => axios.post('/url', data);
// We need a mechanism to get:
// 1. updated values
// 2. re-usable onChange handler
// 3. re-usable onSubmit handler
return (
<form onSubmit={onSubmit}>
<Field
value={values.field}
name="field"
onChange={onChange}
/>
</form>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Let's take 1 big breath and start from
the very start
34 . 2
const {
values,
onChange,
onSubmit,
} = useForm(initialValues, handleSubmit);
const Form = () => {1
const initialValues = {2
field: '',3
};4
5
const handleSubmit = data => axios.post('/url', data);6
7
8
9
10
11
12
13
return (14
<form onSubmit={onSubmit}>15
<Field16
value={values.field}17
name="field"18
onChange={onChange}19
/>20
</form>21
);22
};23
A custom Hook is all we need
34 . 3
const useForm = (initialValues = {}, onSubmit) => {
const [values, setValues] = React.useState(initialValues);
const handleChange = e => {
e.persist();
setValues({
...values,
[e.target.name]: e.target.value
});
};
const handleSubmit = e => {
e.preventDefault();
onSubmit(values);
};
return { values, onChange: handleChange, onSubmit: handleSubmit };
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
We can create a custom Hook with
some internal state
34 . 4
const [values, setValues] = React.useState(initialValues);
const useForm = (initialValues = {}, onSubmit) => {1
2
3
const handleChange = e => {4
e.persist();5
setValues({6
...values,7
[e.target.name]: e.target.value8
});9
};10
11
const handleSubmit = e => {12
e.preventDefault();13
onSubmit(values);14
};15
16
return { values, onChange: handleChange, onSubmit: handleSubmit };17
};18
"useState" Hook does all the
dirty work
34 . 5
const Form = () => {
const initialValues = {
field: '',
};
const handleSubmit = data => axios.post('/url', data);
const {
values,
onChange,
onSubmit,
} = useForm(initialValues, handleSubmit);
return (
<form onSubmit={onSubmit}>
<Field
value={values.field}
name="field"
onChange={onChange}
/>
</form>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Much more readable code
with Hooks
35 . 1
const {
values,
onChange,
onSubmit,
} = useForm(initialValues, handleSubmit);
const { onDoubleCheckSubmit } = useDoubleCheck(onSubmit);
<form onSubmit={onDoubleCheckSubmit}>
const Form = () => {1
const initialValues = {2
field: '',3
};4
5
const handleSubmit = data => axios.post('/url', data);6
7
8
9
10
11
12
13
14
return (15
16
<Field17
value={values.field}18
name="field"19
onChange={onChange}20
/>21
</form>22
);23
};24
Much more readable code
with Hooks
35 . 2
Cleaner components tree with Hooks
36
No more deep dive to test elements
behaviour with Hooks
37
...everyone is happy, so you ship it
38
Code re-usability with some simple functions and not
complex patterns
Much more readable code
No more garbage in components tree
React Hooks prosReact Hooks pros
39
We still need classes for a couple cases:
Error Boundaries
getSnapshotBeforeUpdate
we cannot use Hooks directly inside classes
Do Hooks replace classes?Do Hooks replace classes?
40
Questions
41

The biggest lies about react hooks

  • 1.
    The biggest liesaboutThe biggest lies about React HooksReact Hooks fakiolasmarios@gmail.com twitter.com/@fakiolinho - medium.com/@fakiolinho 1
  • 2.
    Full-stack JavaScript lover,happy husband, proud father Software Engineering Manager / Frontend Head at omilia.com Fakiolas Marios fakiolasmarios@gmail.com - twitter.com/@fakiolinho - medium.com/@fakiolinho Workshops Tutor at 2hog.codes 2
  • 3.
    React HooksReact Hooks React16.8 - 6/2/2019 3 . 1
  • 4.
    React HooksReact Hooks React16.8 - 6/2/2019 3 . 2
  • 5.
    React HooksReact Hooks werecreated so we can winwere created so we can win the fight against evil classesthe fight against evil classes 4 . 1
  • 6.
    React HooksReact Hooks werecreated so we can winwere created so we can win the fight against evil classesthe fight against evil classes 4 . 2
  • 7.
  • 8.
    React HooksReact Hooks werecreated in order to re-use logic without nesting deeper in the components tree ...i am looking at you HOCs and render props 6
  • 9.
    As an architect,you are asked to design a brand new project 7
  • 10.
  • 11.
    Specs indicate thatlots of forms will be implemented 9
  • 12.
    You decide togo with controlled components 10 . 1
  • 13.
    class Form extendsReact.Component { state = { field: '', }; handleSubmit = data => axios.post('/url', data); render() { return ( <form onSubmit={this.handleSubmit}> <input value={this.state.field} onChange={e => ( this.setState({ field: e.target.value }) )} /> </form> ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 A class component is required 10 . 2
  • 14.
    state = { field:'', }; <input value={this.state.field} onChange={e => ( this.setState({ field: e.target.value }) )} class Form extends React.Component {1 2 3 4 5 handleSubmit = data => axios.post('/url', data);6 7 render() {8 return (9 <form onSubmit={this.handleSubmit}>10 11 12 13 14 15 />16 </form>17 );18 }19 Because you need internal state 10 . 3
  • 15.
  • 16.
    ...the project shouldsupport longer forms with multiple fields 12
  • 17.
    Who hates someold-fashioned copy-paste right? 13 . 1
  • 18.
    <form onSubmit={this.handleSubmit}> <input value={this.state.field1} onChange={e =>( this.setState(prevState => ({ ...prevState, field1: e.target.value })) )} /> <input value={this.state.field2} onChange={e => ( this.setState(prevState => ({ ...prevState, field2: e.target.value })) )} /> ... </form> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 13 . 2
  • 19.
  • 20.
    ...the project shouldsupport complex forms with different types of fields 15
  • 21.
    Copy and pastewon't do the job this time 16
  • 22.
    maybe we cancreate some re-usable components and move faster 17
  • 23.
    const Field =({ name="field", value="", type="text", onChange, }) => ( <input name={name} type={type} value={value} onChange={onChange} /> ); 1 2 3 4 5 6 7 8 9 10 11 12 13 Let's create our own Field component 18 . 1
  • 24.
    class Form extendsReact.Component { state = { field: '', }; handleChange = e => this.setState({ [e.target.name]: e.target.value, }); handleSubmit = e => { e.preventDefault(); axios.post('/url', this.state); }; render() { return ( <form onSubmit={this.handleSubmit}> <Field name="field" value={this.state.field} onChange={this.handleChange} /> </form> ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Refactor our Form component 18 . 2
  • 25.
    handleChange = e=> this.setState(prevState => ({ ...prevState, [e.target.name]: e.target.value, })); <Field name="field" value={this.state.field} onChange={this.handleChange} /> <Field.../> class Form extends React.Component {1 state = {2 field: '',3 };4 5 6 7 8 9 10 handleSubmit = e => ...;11 12 render() {13 return (14 <form onSubmit={this.handleSubmit}>15 16 17 18 19 20 21 </form>22 );23 }24 }25 Field component can be re-used easily 18 . 3
  • 26.
    What about formslogic? It is not that re-usable 19 . 1
  • 27.
    state = { field:'', }; handleChange = e => this.setState({ [e.target.name]: e.target.value, }); handleSubmit = e => { e.preventDefault(); axios.post('/url', this.state); }; class Form extends React.Component {1 2 3 4 5 6 7 8 9 10 11 12 13 14 render() {15 return (16 <form onSubmit={this.handleSubmit}>17 <Field18 name="field"19 value={this.state.field}20 onChange={this.handleChange}21 />22 </form>23 );24 }25 }26 Repeated logic across all forms 19 . 2
  • 28.
    Let's provide awrapper that will bring this kind of logic anywhere we like 20
  • 29.
    const Form =() => { const initialValues = { field: "", }; const handleSubmit = data => axios.post('/url', data); return ( <FormHandler initialValues={initialValues} onSubmit={handleSubmit}> {({ values, onChange, onSubmit }) => ( <form onSubmit={onSubmit}> <Field value={values.field} name="field" onChange={onChange} /> </form> )} </FormHandler> ); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Let's use render props pattern 21 . 1
  • 30.
    <FormHandler initialValues={initialValues} onSubmit={handleSubmit}> {({values, onChange, onSubmit }) => ( )} </FormHandler> const Form = () => {1 const initialValues = {2 field: "",3 };4 5 const handleSubmit = data => axios.post('/url', data);6 7 return (8 9 10 <form onSubmit={onSubmit}>11 <Field12 value={values.field}13 name="field"14 onChange={onChange}15 />16 </form>17 18 19 );20 };21 Re-usable logic by using render props 21 . 2
  • 31.
    <form onSubmit={onSubmit}> value={values.field} onChange={onChange} const Form= () => {1 const initialValues = {2 field: "",3 };4 5 const handleSubmit = data => axios.post('/url', data);6 7 return (8 <FormHandler initialValues={initialValues} onSubmit={handleSubmit}>9 {({ values, onChange, onSubmit }) => (10 11 <Field12 13 name="field"14 15 />16 </form>17 )}18 </FormHandler>19 );20 };21 Re-usable logic by using render props 21 . 3
  • 32.
    export default classFormHandler extends React.Component { state = this.props.initialValues; handleChange = e => { e.persist(); this.setState(prevState => ({ ...prevState, [e.target.name]: e.target.value })); }; handleSubmit = e => { e.preventDefault(); this.props.onSubmit(this.state); }; render() { return this.props.children({ values: this.state, onChange: this.handleChange, onSubmit: this.handleSubmit }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Re-usable logic by using render props 21 . 4
  • 33.
    Neat, our formsare looking good 22
  • 34.
    ...the project needsto provide a confirmation step for all the forms that have a destructive purpose 23
  • 35.
    We need aconfirmation step for certain forms 24 . 1
  • 36.
    Should we adda prop named "shouldDoubleCheck" to prevent forms submission at will? <FormHandler shouldDoubleCheck initialValues={initialValues} onSubmit={onSubmit} > ... </FormHandler> 1 2 3 4 5 6 7 24 . 2
  • 37.
    handleSubmit = e=> { e.preventDefault(); if (this.props.shouldDoubleCheckout) { const answer = window.confirm('Are you really sure about this?'); if (answer) { this.props.onSubmit(this.state); } } else { this.props.onSubmit(this.state); } }; 1 2 3 4 5 6 7 8 9 10 11 12 13 Check for "shouldDoubleCheck" across all forms submissions 24 . 3
  • 38.
    This logic willrun across all forms right? Only a few really will use it 25
  • 39.
    We need anotherwrapper that will introduce this confirmation logic 26
  • 40.
    <FormHandler initialValues={initialValues} onSubmit={handleSubmit}> {({values, onChange, onSubmit }) => ( <DoubleCheckHandler onSubmit={onSubmit}> {({ onSubmitWithDoubleCheck }) => ( <form onSubmit={onSubmitWithDoubleCheck}> <Field value={values.field} name="field" label="Field" onChange={onChange} /> </form> )} </DoubleCheckHandler> )} </FormHandler> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Introduce "DoubleCheckHandler" wrapper 27 . 1
  • 41.
    <DoubleCheckHandler onSubmit={onSubmit}> {({ onSubmitWithDoubleCheck}) => ( <form onSubmit={onSubmitWithDoubleCheck}> )} </DoubleCheckHandler> <FormHandler initialValues={initialValues} onSubmit={handleSubmit}>1 {({ values, onChange, onSubmit }) => (2 3 4 5 <Field6 value={values.field}7 name="field"8 label="Field"9 onChange={onChange}10 />11 </form>12 13 14 )}15 </FormHandler>16 Introduce "DoubleCheckHandler" wrapper 27 . 2
  • 42.
    const DoubleCheckHandler =({ onSubmit, children }) => { const handleSubmitWithDoubleCheck = e => { e.preventDefault(); const answer = window.confirm("Are you really sure about this?"); if (answer) { onSubmit(e); } }; return children({ onSubmitWithDoubleCheck: handleSubmitWithDoubleCheck }); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 No "shouldDoubleCheck" prop is needed in DoubleCheckHandler 27 . 3
  • 43.
    Neat, our formsare looking good Let's share all this effort with the teammates 28
  • 44.
    No-one seems tobe excited 29
  • 45.
    "This is notthat readable. How are we going to maintain these components?" 30 . 1
  • 46.
    <FormHandler initialValues={initialValues} onSubmit={handleSubmit}> {({values, onChange, onSubmit }) => ( <DoubleCheckHandler onSubmit={onSubmit}> {({ onSubmitWithDoubleCheck }) => ( ... )} </DoubleCheckHandler> )} </FormHandler> 1 2 3 4 5 6 7 8 9 30 . 2
  • 47.
    "What about allthese wrapping components? Components tree seems pretty ugly" 31 . 1
  • 48.
  • 49.
    "What about testing?How deep we should go to find and tweak a Field?" 32 . 1
  • 50.
    We need touse full mount with enzyme or many dives with shallow testing 32 . 2
  • 51.
    Obviously this solutionisn't that cool 33
  • 52.
    Time to jump1 year ahead and reach Hooks era 34 . 1
  • 53.
    const Form =() => { const initialValues = { field: '', }; const handleSubmit = data => axios.post('/url', data); // We need a mechanism to get: // 1. updated values // 2. re-usable onChange handler // 3. re-usable onSubmit handler return ( <form onSubmit={onSubmit}> <Field value={values.field} name="field" onChange={onChange} /> </form> ); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Let's take 1 big breath and start from the very start 34 . 2
  • 54.
    const { values, onChange, onSubmit, } =useForm(initialValues, handleSubmit); const Form = () => {1 const initialValues = {2 field: '',3 };4 5 const handleSubmit = data => axios.post('/url', data);6 7 8 9 10 11 12 13 return (14 <form onSubmit={onSubmit}>15 <Field16 value={values.field}17 name="field"18 onChange={onChange}19 />20 </form>21 );22 };23 A custom Hook is all we need 34 . 3
  • 55.
    const useForm =(initialValues = {}, onSubmit) => { const [values, setValues] = React.useState(initialValues); const handleChange = e => { e.persist(); setValues({ ...values, [e.target.name]: e.target.value }); }; const handleSubmit = e => { e.preventDefault(); onSubmit(values); }; return { values, onChange: handleChange, onSubmit: handleSubmit }; }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 We can create a custom Hook with some internal state 34 . 4
  • 56.
    const [values, setValues]= React.useState(initialValues); const useForm = (initialValues = {}, onSubmit) => {1 2 3 const handleChange = e => {4 e.persist();5 setValues({6 ...values,7 [e.target.name]: e.target.value8 });9 };10 11 const handleSubmit = e => {12 e.preventDefault();13 onSubmit(values);14 };15 16 return { values, onChange: handleChange, onSubmit: handleSubmit };17 };18 "useState" Hook does all the dirty work 34 . 5
  • 57.
    const Form =() => { const initialValues = { field: '', }; const handleSubmit = data => axios.post('/url', data); const { values, onChange, onSubmit, } = useForm(initialValues, handleSubmit); return ( <form onSubmit={onSubmit}> <Field value={values.field} name="field" onChange={onChange} /> </form> ); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Much more readable code with Hooks 35 . 1
  • 58.
    const { values, onChange, onSubmit, } =useForm(initialValues, handleSubmit); const { onDoubleCheckSubmit } = useDoubleCheck(onSubmit); <form onSubmit={onDoubleCheckSubmit}> const Form = () => {1 const initialValues = {2 field: '',3 };4 5 const handleSubmit = data => axios.post('/url', data);6 7 8 9 10 11 12 13 14 return (15 16 <Field17 value={values.field}18 name="field"19 onChange={onChange}20 />21 </form>22 );23 };24 Much more readable code with Hooks 35 . 2
  • 59.
  • 60.
    No more deepdive to test elements behaviour with Hooks 37
  • 61.
    ...everyone is happy,so you ship it 38
  • 62.
    Code re-usability withsome simple functions and not complex patterns Much more readable code No more garbage in components tree React Hooks prosReact Hooks pros 39
  • 63.
    We still needclasses for a couple cases: Error Boundaries getSnapshotBeforeUpdate we cannot use Hooks directly inside classes Do Hooks replace classes?Do Hooks replace classes? 40
  • 64.