简体   繁体   中英

React sharing method across components

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!

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) => {
    const { type, checked, name, value} = e.target;
    const value = type === 'checkbox' ? checked : value;
    const name = name;

    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.

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.

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.

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 !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM