use-prop-change
React hook for simplifying setState
decomposition into smaller setters for particular state parts.
It can usefull when you need:
- transfer control over part of the state to another component;
- set or change some data in nested state tree;
- simplify working with forms without big library;
$ npm install use-prop-change
or
$ yarn add use-prop-change
import React, { useState } from "react";
import usePropChange from "use-prop-change";
import Friends from "./Friends"; // this component responsible for friends field
const forInput = (handler) => (e) => handler(e.target.value);
const defaultPerson = {
name: "Dasha",
age: "23",
friends: [
/* whatever here */
],
};
export const PersonForm = () => {
const [person, setPerson] = useState(defaultPerson);
const handlePersonProp = usePropChange(setPerson);
return (
<form onSubmit={/* do something */}>
<input
value={person.name}
onChange={forInput(handlePersonProp("name"))}
/>
<input value={person.age} onChange={forInput(handlePersonProp("age"))} />
<Friends
friends={person.friends}
onFriendsChange={handlePersonProp("friends")}
/>
</form>
);
};
use-prop-change
use ramda lens under the hood.
But you don't need understand them to use this hook.
For example above we can replace
const handlePersonProp = usePropChange(setPerson);
to
const handlePersonProp = (name) => (value) => {
setPerson((prevState) => ({
...prevState,
[name]: typeof value === "function" ? value(prevState[name]) : value,
}));
};
But note, handlePersonProp
returned from usePropChange
more powerfull:
- if first argument is number, new state will be an Array
- if first argument is string, new state will be an Object
- if first argument is array, state will be changed on this path
- 2 arguments (name and value) can be passed together, to just make changes once
You can see all this on example