用多次返回来破坏自定义 React Hook 的更好方法?

Ven*_*sky 6 javascript reactjs react-hooks

语境:

我看到了 react hooks 的文档,所有的 hooks 都返回两个在数组中被破坏的值。但是如果我有一个钩子返回一个多于两个的数组,像这样:

const [value, someMethod, someMethod2, someMethod3, someMethod4] = useSomeMethod(someValue)

但我只想要一些方法,而不是全部。在这种情况下,我需要执行以下操作:

const [value, , , someMethod3, someMethod4] = useSomeMethod(someValue)

这样,它看起来并没有那么糟糕,但是想象一下,如果您有一个返回超过 10 的钩子。我将展示一个真实的例子,这样它会更清楚。

真实例子:

我正在创建一个用于处理数组的钩子,所以它会是这样的:

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]
}
Run Code Online (Sandbox Code Playgroud)

并使用这个钩子,它会像:

const [bananas, addBananas, deleteBananasByIndex, updateBananasByIndex] = useArray(someBananas)

但是如果你知道一点数组操作的话,有不止 3 种方法,可能不止 10 种。

我想要做的是为数组创建一个钩子,它可以处理数组的所有类型的操作,并在我的项目中的任何地方使用它。

问题:

当我要使用这个钩子时,问题就来了,因为当我调用这个钩子时,所有的方法都不会被使用,但是所有的方法都将在项目中使用。并且只使用其中的一些方法,它会是这样的:

const [value, oneMethod, , , someMethod, , otherMethod, , moreMethod] = useSomeMethod(someValue)

我认为这很糟糕,因为我需要记住其他方法并且使用很多,看起来不太好。

我想将它解构为一个对象,但名称将是固定的,而且我将无法useArray在组件中使用更多的名称

所以,考虑到所有这些......

是否有比记住返回顺序并使用大量返回值更好的方法来破坏具有多个返回值的自定义 React Hook ,

观察:我的问题不是关于数组,而是关于破坏反应钩子的返回

Ven*_*sky 8

更新

正如@worc在评论中所说,useReducer是一种更好的方法,也是正确的方法,像这样的情况应该使用useReducer.

另外,它的工作原理如下:

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)
}
Run Code Online (Sandbox Code Playgroud)

感谢所有提供帮助的人!


所以这样做的方法是返回一个对象并重命名所有变量

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)
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以返回一个对象而不是数组

所以,

 return {obj1, obj2, obj3,..} 
Run Code Online (Sandbox Code Playgroud)

并使用

const {obj1, obj3} = useHook();
Run Code Online (Sandbox Code Playgroud)