I have a custom react hook:
function useItem(id) {
const [value, setValue] = useState();
useEffect(() => {
databaseRead(id).then(i => setValue(i));
}, [id]);
function setItem(i) {
setValue(i);
}
function writeItem(i) {
databaseWrite(id, i);
}
return [value, setItem, writeItem];
}
When using a hook like this in a component, the returned writeItem function changes every time the value changes (presumably because I create a new array every time).
How can I avoid re-renders of the Button component when I use my hook in an Item like so?
function Item(props) {
const [item, setItem, writeItem] = useItem(props.id);
return(
<>
<ItemEditor data={item} setItem={setItem}/>
<Button onPress={writeItem}/>
</>
)
}
My current working but awkward approach is to return a useRef object instead of the array from my hook:
function useItem(id) {
const retVal = useRef({
value: value,
setItem: setItem,
writeItem: writeItem
}).current;
const [dirty, setDirty] = useState();
function makeDirty() { setDirty(Math.random()); }
//and instead of setValue(i) do retVal.value=i; makeDirty();
return retVal;
}
Many thanks!
I have a custom react hook:
function useItem(id) {
const [value, setValue] = useState();
useEffect(() => {
databaseRead(id).then(i => setValue(i));
}, [id]);
function setItem(i) {
setValue(i);
}
function writeItem(i) {
databaseWrite(id, i);
}
return [value, setItem, writeItem];
}
When using a hook like this in a component, the returned writeItem function changes every time the value changes (presumably because I create a new array every time).
How can I avoid re-renders of the Button component when I use my hook in an Item like so?
function Item(props) {
const [item, setItem, writeItem] = useItem(props.id);
return(
<>
<ItemEditor data={item} setItem={setItem}/>
<Button onPress={writeItem}/>
</>
)
}
My current working but awkward approach is to return a useRef object instead of the array from my hook:
function useItem(id) {
const retVal = useRef({
value: value,
setItem: setItem,
writeItem: writeItem
}).current;
const [dirty, setDirty] = useState();
function makeDirty() { setDirty(Math.random()); }
//and instead of setValue(i) do retVal.value=i; makeDirty();
return retVal;
}
Many thanks!
Share Improve this question asked May 5, 2020 at 15:44 Staffan_KStaffan_K 1331 gold badge1 silver badge6 bronze badges1 Answer
Reset to default 21You can make use of useCallback
hook to memoize the functions so that they aren't created again on each render
function useItem(id) {
const [value, setValue] = useState();
useEffect(() => {
databaseRead(id).then(i => setValue(i));
}, [id]);
const setItem = useCallback(function(i) {
setValue(i);
}, []);
const writeItem = useCallback(function(i) {
databaseWrite(id, i);
}, [id]) // this depends on id, and need to be recreated on id change
return [value, setItem, writeItem];
}