简体   繁体   中英

How to make functions that change the state via useState hook reusable?

Let's say I have the following code for changing the input values and it updates the state of the component:

const handleInputChange = e => {
    let value = e.target.value;
    let name = e.target.name;
    let type = e.target.type;

    // some other code

    setInput(nextState);
  };

However, since I have different components using this same function, I'd like to make it an exportable utility function. But then it has the “setInput” function call coming from useState hook.

Should I just pass the setInput as a parameter to every handleInputChange() call like:

onChange={e => handleInputChange(e, setInput)}

Or is there a better way of handling this?

If you are creating a custom hook, you can just call other hooks in there. So you could just retrieve setInput within the hook instead of passing it in there:


const useCustomHook = (initialValue) => {

  const [input, setInput] = useState(initialValue);

  // ...

  const handleInputChange = e => {
    let value = e.target.value;
    let name = e.target.name;
    let type = e.target.type;

    // some other code

    setInput(nextState);
  };

  return handleInputChange;
}

This input would be bound to the state of the component, which is calling useCustomHook .

EDIT:

Combining @Shota's answer with this one, you could create a component using the useState hook to handle the state internally aswell:


const CustomInput(initialState) => {

  const [input, setInput] = useState(initialValue);

  const handleInputChange = e => {
    // ...
    setInput(nextState);
  };

  return (<input type="text" onChange={handleInputChange} />);
} 

To use input in the outside world just return it from the hook:


useCustomHook = () => {
  // ...
  return {
    handleInputChange,
    input
  }
}

You can create a brand new reusable component with the on change function prop.

import React from 'react';

const CommonInput = ({handleChange}) => {

  const handleInputChange = e => {
    let value = e.target.value;
    let name = e.target.name;
    let type = e.target.type;

    // some other code

    setInput(nextState);
    handleChange(nextState);
  };

  return (<input type="text" onChange={handleInputChange} />);
}

export default CommonInput;

And we can reuse it anywhere we want:

import React from 'react';

const Parent = (props) => (
  <CommonInput handleChange={nextStateData => {}}/>
  );

export default Parent;

Generally, I would prefer creating a new component with some functionality inside than reusing just functions.

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