猿问

来自自定义钩子的状态在父级而不是子级中使用减速器更新

我有一个使用 useReducer 的自定义钩子,它控制在仪表板上呈现哪些组件。它在父组件中按预期工作,但是当我在子组件中使用它时,useReducer 运行,状态发生了变化,但它在父组件中没有改变,所以它没有通过适当的更改重新渲染。我在减速器中使用扩展运算符返回一个新对象。我已经在钩子内尝试了一些带有额外 useStates 和 useEffects 的 hacky 东西,但它们都没有产生影响。我尝试了不同级别的解构,也没有效果。我可以看到状态正在更改,但在父对象中返回时似乎没有被识别为新对象。


自定义挂钩


import { useReducer } from "react"


let dashboard = {}


export const dashboardReducer = (state, action) => {

    console.log("dashboardReducer: state, action=", state, action)

    switch (action.component) {

        case 'lowerNav':

            switch (action.label) {

                case 'journal':

                return { ...state, lowerNav: 'journal'}

                case 'progress':

                return { ...state, lowerNav: 'progress'}

                case 'badges':

                return { ...state, lowerNav: 'badges'}

                case 'challenges':

                return { ...state, lowerNav: 'challenges'}

                case 'searchResults':

                return { ...state, lowerNav: 'searchResults'}

            }

        case 'foodSearchBox' :

            if (action.searchResults) {

                return { ...state, searchResults: action.searchResults, lowerNav: "searchResults"}

            } else {

                return { ...state, searchResults: "NO SEARCH RESULTS"}                

            }

        default:

            throw new Error()

    }

}


export const useDashboard = () => {

    const [ state, dispatch ] = useReducer(dashboardReducer, dashboard)

    //fires on every dispatch no matter which component

    console.log("useDashboard: state=", state)      

    return [ state, dispatch ]

}


export const initDashboard = initialState => {

    dashboard = initialState

}

我正在尝试从最初使用 useState 钩子在各处传递的大量凌乱的道具钻孔中重构。我正在使用 Next.js,我试图远离使用 Context API 或引入 Redux。我真的只需要在单个页面组件上保持状态,它实际上只是本地 UI 状态,因为我正在使用 apollo-hooks 处理大部分数据。



慕哥6287543
浏览 73回答 1
1回答

富国沪深

您在子组件中调用的调度函数与父组件中的调度函数不同,它不会更新相同的状态。钩子的不同用法useDashboard返回不同的(状态,调度)对,它们不会相互影响。如果您希望父组件的状态可以从子组件更改,但又不想使用上下文 API,则必须将父组件的调度函数(或使用它的回调)作为子组件传递给子组件支柱。const Parent = () => {&nbsp; const [state, dispatch] = useDashboard();&nbsp; return (&nbsp; &nbsp; <Child&nbsp; &nbsp; &nbsp; updateFoodSearch={(listItems) =>&nbsp; &nbsp; &nbsp; &nbsp; dispatch({ component: "foodSearchBox", listItems })&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; />&nbsp; );};
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答