【问题标题】:Better aproach for destructing Custom React Hooks with multiple returns?破坏具有多个返回的自定义 React Hooks 的更好方法?
【发布时间】:2019-03-22 12:14:27
【问题描述】:

上下文:

我看到了 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]
}

要使用这个钩子,就像:

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

但是如果你对数组操作有点了解的话,方法远不止3种,可能不止10种。

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

问题:

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

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

我认为这是非常糟糕,因为我需要记住其他方法,并且还使用很多,看起来不错。

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

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

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

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

【问题讨论】:

  • 为什么不返回一个对象,而使用对象破坏呢?
  • 你可以在像这样const { foo: bar } = { foo: 7 }这样的对象解构后重命名变量
  • 这对于useReducer 来说可能更好吗?您可以根据这些操作修改操作和状态
  • 作者在开头打错了of,而不是o。这个问题应该被搁置,标记为重复,过于宽泛,然后关闭。
  • @ZenVentzi Typo 已修复,你能解释一下为什么它应该是 put on hold, marked as a duplicate, too broad and then closed 吗?什么是欺骗问题?

标签: javascript reactjs react-hooks


【解决方案1】:

更新

正如@worc在cmets中所说,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)
}

感谢所有提供帮助的人!


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

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)

【讨论】:

    【解决方案2】:

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

    所以,

     return {obj1, obj2, obj3,..} 
    

    并使用

    const {obj1, obj3} = useHook();
    

    【讨论】:

      【解决方案3】:

      您可以对函数的返回值使用过滤器,然后只取所需的值并解构(如果您无法更改数据结构)

      const [value, oneMethod, someMethod, otherMethod, moreMethod] = useSomeMethod(someValue).filter((_,index)=> select desired index only)
      

      如果您可以更改结构,只需使用 object 而不是解构

      const { foo: bar } = { foo: 7 , xyz: some value}
      

      【讨论】:

        【解决方案4】:

        您可以返回一个对象而不是一个数组,然后使用点符号来访问所需的函数。

                export function useCustomHook(data) {
                const dispatch = useDispatch();
                
            
                const Notify = (data) => {
                    return dispatch(openNotifyModal({ show: true, title: data.title, message: data.message }))
                }
                
                const OpenLogin = () => {
                    return dispatch(openLoginModal());
                }
            
                const OpenLoader = () => {
                    return dispatch(openLoaderModal());
                }
            
                const CloseLoader = () => {
                    return dispatch(closeLoaderModal());
                }
            
                return {Notify, OpenLoader, CloseLoader, OpenLogin};
            
            }
            
        // in your main component import useCustomHook
            let customHook = useCustomHook();
            
            const myFunc = () => {
            return customHook.Notify({title:'demo title', message:'demo message'});
            }
        
        
           
        

        【讨论】:

          猜你喜欢
          • 2019-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-23
          相关资源
          最近更新 更多