useReducer 状态更新不会在另一个组件中重新渲染 useEffect 及其依赖项

pep*_*969 2 reactjs use-reducer

我有一个父组件,它根据 useReducer 中名为 state.viewOption 的状态选择要渲染的视图。

调度它的子组件类似于:

export default function SearchFilter({ placeholder, onSearch }) {

    const [state, dispatch] = useReducer(
        collectionListReducer,
        initialCollectionState
    );

const option = state.viewOption;
  
    const handleChange = e => dispatch(setSketchesTrendsOption(e.target.value));

    return (
 <Grid container>
            <Grid item className={classes.selector}>
                <TextField
                    select
                    id="sketches-trends-selector"
                    value={option}
                    onChange={handleChange}
                >
                    <MenuItem value="Sketches">{t('TR_SKETCHES')}</MenuItem>
                    <MenuItem value="Trends">{t('TR_TRENDS')}</MenuItem>
                </TextField>
            </Grid>
   );
}
Run Code Online (Sandbox Code Playgroud)

然后我想根据这个状态选择视图选项的父组件是这样的:

export default function CollectionListOption() {
    const [state, dispatch] = useReducer(
        collectionListReducer,
        initialCollectionState
    );

const viewOption = state.viewOption;

 useEffect(() => {

        console.log('view option in useEffect', viewOption);

    }, [viewOption]);


    switch (viewOption) {
        case 'Sketches':
            return <SketchesList />;
        case 'Trends':
            return <TrendsList />;
        default:
            return <SketchesList />;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,<CollectionListOption/>一旦state.viewOption更改了该组件的值以显示正确的视图,我想重新渲染该组件。但我不知道为什么它只在安装时以及当我触发状态<SearchFilter/> 更改中的调度时呈现控制台日志<SearchFilter/>,但我的状态<CollectionListOption/>没有注意到并且未触发 useEffect 。

谢谢你!

pep*_*969 5

感谢@ChrisFarmer 评论,这就是我解决问题的方法:

添加了一个名为 CollectionStateProvider 的新组件:

const CollectionStateContext = createContext();
    
    export default function CollectionStateProvider({ children }) {
        const [state, dispatch] = useReducer(
            collectionListReducer,
            initialCollectionState
        );
        return (
            <CollectionStateContext.Provider value={[state, dispatch]}>
                {children}
            </CollectionStateContext.Provider>
        );
    }
    
    export const useCollectionState = () => useContext(CollectionStateContext);
Run Code Online (Sandbox Code Playgroud)

然后,在这两个组件中,useReducer我没有导入 ,而是将其导入useCollectionState为:

const [state, dispatch] = useCollectionState();
Run Code Online (Sandbox Code Playgroud)