Reputation: 427
I have a component that looks like this so far:
import React from 'react';
// Import images
import logo from '../images/logo-small.png';
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
I'm going to be reusing the same handleChange(e)
method across multiple components across multiple files on my app. Is there a way I can separate out this method instead of having to rewrite it each time?
Would I put handleChange(e)
into a file names utils.js
and import that file each time I need to use it? If so, how do I make sure that this.setState
works properly?
I have some rough ideas on how to go about this (such as the one above), but I want to take the best approach to this. Thanks!
Upvotes: 5
Views: 6333
Reputation: 225
Hooks are another way to go.
With custom hooks you can reuse your state dependent handlers with ease between components.
// hooks.js
const { useState } from 'react';
const useHandleChange = () => {
const [formValues, setFormValues] = useState({});
const handleChange = (e) => {
let { type, checked, name, value} = e.target;
value = type === 'checkbox' ? checked : value;
setFormValues({
[name]: value
});
};
return { formValues, handleChange };
}
// Component.js
import useHandleChange from './hooks';
const LoginForm = () => {
// you can use that on each component that needs the handleChange function
const { formValues, handleChange } = useHandleChange();
return (
// html template
);
};
You would need to convert your component to function component, though so I would propose this solution only if it doesn't require too much effort to refactor your code. Hooks does not work on class components.
Upvotes: 9
Reputation: 2860
I guess simply create new file for example utils.js
and export your functions from it as below
const handleChange = (e) => {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
return { [name]: value }
}
export.handler = handleChange;
than import it in your file, for example like this:
const utils = require('path/to/file');
setState(utils.handleChange(e));
happy codding !
Upvotes: 1
Reputation: 2930
Of course. What you are looking for is called Higher-Order Components
You can create a HOC with all the methods/logic you need to share across, and wrap the components you need to enhance with it.
Upvotes: 1
Reputation: 7355
You certainly could create a helper function. However, it's nice to have your setState()
in the component that holds the state.
To that end, you could do something like this:
// utils.js helper function
handleCheckbox(e) {
const target = e.target,
value = target.type === 'checkbox' ? target.checked : target.value;
return {name: target.name, value: value};
}
// In your component
handleChange(e) {
// Destructured in case you need to handle it differently
const { name, value } = handleCheckbox(e);
this.setState({[name]: value});
}
The helper could pass {[name]: value}
, but it shouldn't necessarily be concerned with how the variables are finally used.
Upvotes: 0