Javier Ponce
Dec 19, 2019
Why You Should Avoid Using Redux for Your Forms
Javier Ponce
Dec 19, 2019
Why You Should Avoid Using Redux for Your Forms
Javier Ponce
Dec 19, 2019
Why You Should Avoid Using Redux for Your Forms
Javier Ponce
Dec 19, 2019
Why You Should Avoid Using Redux for Your Forms
Javier Ponce
Dec 19, 2019
Why You Should Avoid Using Redux for Your Forms
Why You Should Avoid Using Redux for Your Forms
In recent years, we have learned to use Redux with simple applications like todo-lists or forms, but are these a good example? What if our application has grown considerably?
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
In this case, we are just reaching our single reducer when dispatching an action:
This may be “OK” for small apps but the latency will continue to increase as our app grows. Now, imagine that we have 50 reducers:
We will be hitting all the reducers on EVERY SINGLE KEYSTROKE.
As Dan Abramov says, forms are ephemeral and local. The redux state is intended to be global. Using a local state is fine, and if we need to share these values, we can lift up your state to the closest common ancestor.Handling the state locally
This is the same form using a local state:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Name:
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
E-mail:
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Message:
<textarea
name="message"
type="text"
value={this.state.comments}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
With this approach we get the following benefits:
No need to hit any reducer
Better performance. Plus, this won’t be affected even if the app continues to grow (having more reducers)
But, what if we want to have more forms? Do we need copy-paste the handleInputChange
function for each form? Or what if we need to run validations? Is there a way to avoid all this boilerplate code?
The answer to these questions is a nice alternative: Formik.
Formik does all this magic for us under the hood. I won’t cover how to use Formik in this post since it provides good documentation. However, I would like to mention that Formik + Yup will solve most of your problems.
Are you interested in looking at Formik in more depth? Let me know in the comments!
Conclusion
Using the local state on React is usually better. You should use Redux for complex state transitions, when you need to keep track of the changes or when it matters globally.
...
I created this repository which demonstrates the performance impact with lots of forms, feel free to take a look!: https://github.com/densitylabs/blog-reference-examples/tree/master/redux-in-forms
Why You Should Avoid Using Redux for Your Forms
In recent years, we have learned to use Redux with simple applications like todo-lists or forms, but are these a good example? What if our application has grown considerably?
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
In this case, we are just reaching our single reducer when dispatching an action:
This may be “OK” for small apps but the latency will continue to increase as our app grows. Now, imagine that we have 50 reducers:
We will be hitting all the reducers on EVERY SINGLE KEYSTROKE.
As Dan Abramov says, forms are ephemeral and local. The redux state is intended to be global. Using a local state is fine, and if we need to share these values, we can lift up your state to the closest common ancestor.Handling the state locally
This is the same form using a local state:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Name:
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
E-mail:
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Message:
<textarea
name="message"
type="text"
value={this.state.comments}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
With this approach we get the following benefits:
No need to hit any reducer
Better performance. Plus, this won’t be affected even if the app continues to grow (having more reducers)
But, what if we want to have more forms? Do we need copy-paste the handleInputChange
function for each form? Or what if we need to run validations? Is there a way to avoid all this boilerplate code?
The answer to these questions is a nice alternative: Formik.
Formik does all this magic for us under the hood. I won’t cover how to use Formik in this post since it provides good documentation. However, I would like to mention that Formik + Yup will solve most of your problems.
Are you interested in looking at Formik in more depth? Let me know in the comments!
Conclusion
Using the local state on React is usually better. You should use Redux for complex state transitions, when you need to keep track of the changes or when it matters globally.
...
I created this repository which demonstrates the performance impact with lots of forms, feel free to take a look!: https://github.com/densitylabs/blog-reference-examples/tree/master/redux-in-forms
Why You Should Avoid Using Redux for Your Forms
In recent years, we have learned to use Redux with simple applications like todo-lists or forms, but are these a good example? What if our application has grown considerably?
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
In this case, we are just reaching our single reducer when dispatching an action:
This may be “OK” for small apps but the latency will continue to increase as our app grows. Now, imagine that we have 50 reducers:
We will be hitting all the reducers on EVERY SINGLE KEYSTROKE.
As Dan Abramov says, forms are ephemeral and local. The redux state is intended to be global. Using a local state is fine, and if we need to share these values, we can lift up your state to the closest common ancestor.Handling the state locally
This is the same form using a local state:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Name:
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
E-mail:
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Message:
<textarea
name="message"
type="text"
value={this.state.comments}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
With this approach we get the following benefits:
No need to hit any reducer
Better performance. Plus, this won’t be affected even if the app continues to grow (having more reducers)
But, what if we want to have more forms? Do we need copy-paste the handleInputChange
function for each form? Or what if we need to run validations? Is there a way to avoid all this boilerplate code?
The answer to these questions is a nice alternative: Formik.
Formik does all this magic for us under the hood. I won’t cover how to use Formik in this post since it provides good documentation. However, I would like to mention that Formik + Yup will solve most of your problems.
Are you interested in looking at Formik in more depth? Let me know in the comments!
Conclusion
Using the local state on React is usually better. You should use Redux for complex state transitions, when you need to keep track of the changes or when it matters globally.
...
I created this repository which demonstrates the performance impact with lots of forms, feel free to take a look!: https://github.com/densitylabs/blog-reference-examples/tree/master/redux-in-forms
Why You Should Avoid Using Redux for Your Forms
In recent years, we have learned to use Redux with simple applications like todo-lists or forms, but are these a good example? What if our application has grown considerably?
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
In this case, we are just reaching our single reducer when dispatching an action:
This may be “OK” for small apps but the latency will continue to increase as our app grows. Now, imagine that we have 50 reducers:
We will be hitting all the reducers on EVERY SINGLE KEYSTROKE.
As Dan Abramov says, forms are ephemeral and local. The redux state is intended to be global. Using a local state is fine, and if we need to share these values, we can lift up your state to the closest common ancestor.Handling the state locally
This is the same form using a local state:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Name:
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
E-mail:
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Message:
<textarea
name="message"
type="text"
value={this.state.comments}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
With this approach we get the following benefits:
No need to hit any reducer
Better performance. Plus, this won’t be affected even if the app continues to grow (having more reducers)
But, what if we want to have more forms? Do we need copy-paste the handleInputChange
function for each form? Or what if we need to run validations? Is there a way to avoid all this boilerplate code?
The answer to these questions is a nice alternative: Formik.
Formik does all this magic for us under the hood. I won’t cover how to use Formik in this post since it provides good documentation. However, I would like to mention that Formik + Yup will solve most of your problems.
Are you interested in looking at Formik in more depth? Let me know in the comments!
Conclusion
Using the local state on React is usually better. You should use Redux for complex state transitions, when you need to keep track of the changes or when it matters globally.
...
I created this repository which demonstrates the performance impact with lots of forms, feel free to take a look!: https://github.com/densitylabs/blog-reference-examples/tree/master/redux-in-forms
Why You Should Avoid Using Redux for Your Forms
In recent years, we have learned to use Redux with simple applications like todo-lists or forms, but are these a good example? What if our application has grown considerably?
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
// Basic contact form
const Form = ({
name,
email,
message,
setFieldValue,
}) => {
return (
<div className="form">
<label>
Name:
<input
id="name"
type="text"
value={name}
onChange={e => setFieldValue('name', e.target.value)}
/>
</label>
<br />
<label>
E-mail:
<input
id="email"
type="email"
value={email}
onChange={e => setFieldValue('email', e.target.value)}
/>
</label>
<br />
<label>
Message:
<textarea
id="message"
value={message}
onChange={e => setFieldValue('message', e.target.value)}
/>
</label>
<br />
<button type="submit">Send your message</button>
</div>
);
}
In this case, we are just reaching our single reducer when dispatching an action:
This may be “OK” for small apps but the latency will continue to increase as our app grows. Now, imagine that we have 50 reducers:
We will be hitting all the reducers on EVERY SINGLE KEYSTROKE.
As Dan Abramov says, forms are ephemeral and local. The redux state is intended to be global. Using a local state is fine, and if we need to share these values, we can lift up your state to the closest common ancestor.Handling the state locally
This is the same form using a local state:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: ''
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Name:
<input
name="name"
type="text"
value={this.state.name}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
E-mail:
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Message:
<textarea
name="message"
type="text"
value={this.state.comments}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
With this approach we get the following benefits:
No need to hit any reducer
Better performance. Plus, this won’t be affected even if the app continues to grow (having more reducers)
But, what if we want to have more forms? Do we need copy-paste the handleInputChange
function for each form? Or what if we need to run validations? Is there a way to avoid all this boilerplate code?
The answer to these questions is a nice alternative: Formik.
Formik does all this magic for us under the hood. I won’t cover how to use Formik in this post since it provides good documentation. However, I would like to mention that Formik + Yup will solve most of your problems.
Are you interested in looking at Formik in more depth? Let me know in the comments!
Conclusion
Using the local state on React is usually better. You should use Redux for complex state transitions, when you need to keep track of the changes or when it matters globally.
...
I created this repository which demonstrates the performance impact with lots of forms, feel free to take a look!: https://github.com/densitylabs/blog-reference-examples/tree/master/redux-in-forms
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.