I saw the documentation of react hooks and all the hooks return two values that are destructed in an array. But what if I have a hooks that returns an array with much more than two, like this:
const [value, someMethod, someMethod2, someMethod3, someMethod4] = useSomeMethod(someValue)
But I only want some of the methods, not all of then. In this case I will need to do something like:
const [value, , , someMethod3, someMethod4] = useSomeMethod(someValue)
And this way, it doesn't look that bad, but imagine if you have a hook that returns more than 10. I will show a real example so it can be more clear.
I'm creating a hook for dealing with arrays, so it would be something like:
const useArray = (initialState) => {
const [array, setArray] = useState(initialState)
const add = (value) => {
let newArray = [...array, value]
setArray(newArray)
}
const deleteByIndex = (index) => {
let newArray = array.filter((x, i) => i != index)
setArray(newArray)
}
const updateByIndex = (value, index) => {
let newArray = [...array]
newArray[index] = value
setArray(newArray)
}
return [array, add, deleteByIndex, updateByIndex]
}
and to use this hook, it would be like:
const [bananas, addBananas, deleteBananasByIndex, updateBananasByIndex] = useArray(someBananas)
But if you know a little bit of array manipulation, there is much more than 3 methods, maybe more than 10.
What I want to do is create a hooks for arrays that can handle all types of manipulations for an array and use it anywhere in my project.
The problem comes when I'm going to use this hooks, because all methods aren't going to be use when I call the hook, but all methods are going to be used in the project. And to use only some of the methods, it would be something like this:
const [value, oneMethod, , , someMethod, , otherMethod, , moreMethod] = useSomeMethod(someValue)
I thinks this is very bad because I need to remember the other of the methods and also using alot of ,
doesn't look good.
I thought of deconstruct it as an object, but than the names would be fixed and also I wouldn't be able to use more that one useArray
in a component.
So, taking all of this in consideration...
Is there a better aproach for destructing Custom React Hooks with multiple returns than remembering the order of the returns and using alot of ,
?
Observations: My question isn't about arrays, is about destructing the return of a react hook
As @worc said in the comments, useReducer
is a better aproach and also the correct aproach, cases like this are supossed to use useReducer
.
Also, here is how it would work:
function arrayReducer(array, action) {
switch (action.type) {
case 'push':
return [...array, action.value]
case 'deleteByIndex':
let deleteByIndex = array.filter((x, i) => i != action.index)
return deleteByIndex
case 'updateByIndex':
let updateByIndex = [...array]
updateByIndex[action.index] = action.value
return updateByIndex
default:
throw new Error()
}
}
export default function useArray(initialState){
return useReducer(arrayReducer, initialState)
}
Thanks for everybody that helped!
So the way of doing this is returning an object and renaming all of the variables
const useArray = (initialState) => {
const [array, setArray] = useState(initialState)
const add = (value) => {
let newArray = [...array, value]
setArray(newArray)
}
const deleteByIndex = (index) => {
let newArray = array.filter((x, i) => i != index)
setArray(newArray)
}
const updateByIndex = (value, index) => {
let newArray = [...array]
newArray[index] = value
setArray(newArray)
}
return {array, add, deleteByIndex, updateByIndex}
}
const {
array: bananas,
add: addBananas,
deleteByIndex: deleteBananasByIndex,
updateByIndex: updateBananasByIndex
} = useArray(someBananas)
You can return an object instead of an array
so,
return {obj1, obj2, obj3,..}
and use
const {obj1, obj3} = useHook();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With