【问题标题】:useReducer state update doesn't rerender a useEffect in another component with it's dependencyuseReducer 状态更新不会在具有依赖关系的另一个组件中重新渲染 useEffect
【发布时间】:2021-08-19 18:07:55
【问题描述】:

我有一个父组件,它根据 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>
   );
}

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

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 />;
    }
}

问题是,一旦state.viewOption 更改了它的值以显示正确的视图,我想重新渲染这个组件&lt;CollectionListOption/&gt;。但我不知道为什么它只在挂载时呈现控制台日志,当我在&lt;SearchFilter/&gt; @state 中触发调度时&lt;SearchFilter/&gt;但我的状态在&lt;CollectionListOption/&gt;doesn 没有注意到并且useEffect 没有被触发。

谢谢!

【问题讨论】:

  • 您的状态不会在两个组件之间共享。听起来您可能需要一些反应共享状态解决方案。哪一个最适合您可能取决于您的应用程序真正需要做什么。根据您在此处显示的内容,我可能只是选择一个自定义上下文。
  • @ChrisFarmer 你是对的!我认为您可以使用 useReducer 钩子从另一个组件获取状态更新,但我肯定需要为此使用上下文提供程序,然后它们共享完全相同的状态。谢谢!

标签: reactjs use-reducer


【解决方案1】:

感谢@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);

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

const [state, dispatch] = useCollectionState();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-23
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2020-08-18
    • 2021-05-19
    相关资源
    最近更新 更多