Skip to content

Instantly share code, notes, and snippets.

@muhsalaa
Last active June 12, 2020 05:51
Show Gist options
  • Save muhsalaa/d82b85bd392ae5a99aade07e6a8ea2bc to your computer and use it in GitHub Desktop.
Save muhsalaa/d82b85bd392ae5a99aade07e6a8ea2bc to your computer and use it in GitHub Desktop.
Handling large amount of iterated form field with react hooks
import React, { useState, useCallback, useRef, useEffect } from 'react';
export default function Multipleform() {
let [data, setData] = useState([...Array(5000).fill('')]);
// wrap handler with useCallback to keep its reference
// so React.memo will not consider it change overtime
const handler = useCallback((value = '', i = 0) => {
setData((state) => {
// return state modified with map to change value of certain index
// value ?? "" is null coalescing
// null ?? 90 -> 90 || undefined ?? 90 -> 90
// false or 0 or '' or any falsy value except null and undefined will return its right hand
// false ?? 90 - 0 ?? 89 -> 89
return state.map((x, index) => (index === i ? value ?? '' : x));
});
}, []);
return (
<div>
<h1>Form</h1>
{/* to log current state */}
<button onClick={() => console.log(data)}>log state</button>
{/* just print string of array to see state (ref value) changes */}
<p>{data.filter(Boolean).toString()}</p>
{data.map((x, i) => {
return <MemoizedField data={x} index={i} key={i} handler={handler} />;
})}
</div>
);
}
// memoized form field
const MemoizedField = React.memo(({ data, handler, index }) => {
useCountRenders(data, index);
return (
<input value={data} onChange={(e) => handler(e.target.value, index)} />
);
});
// custom hooks to see re renders count of certain component
const useCountRenders = (data, index) => {
const renders = useRef(0);
useEffect(() => console.log('renders: ', renders.current++, 'for =', index), [
data,
index,
]);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment