代码之家  ›  专栏  ›  技术社区  ›  AlwaysNeedingHelp

使用CombinedReducers时,调度操作不会触发呈现

  •  0
  • AlwaysNeedingHelp  · 技术社区  · 7 年前

    当我不使用CombineReducers时:

    const store = createStore<StoreState,any,any,any>(pointReducer, {
        points: 1,
        languageName: 'Points',
    });
    
    function tick() {
        store.dispatch(gameTick());
        requestAnimationFrame(tick)
    }
    
    tick();
    

    一切正常,组件更新。但是当我这样做的时候:

    const reducers = combineReducers({pointReducer}) as any;
    
    const store = createStore<StoreState,any,any,any>(reducers, {
        points: 1,
        languageName: 'Points',
    });
    

    商店 更新(由控制台日志检查),但是组件不呈现更改,我不知道为什么!

    减速器:

    export function pointReducer(state: StoreState, action: EnthusiasmAction): StoreState {
        switch (action.type) {
            case INCREMENT_ENTHUSIASM:
                return { ...state, points: state.points + 1 };
            case DECREMENT_ENTHUSIASM:
                return { ...state, points: Math.max(1, state.points - 1) };
            case GAME_TICK:
                return { ...state, points: state.points + 1 };
            default:
                return state;
        }
    }
    

    和组件:

    export interface Props {
        name: string;
        points: number;
        onIncrement: () => void;
        onDecrement: () => void;
    }
    
    class Points extends React.Component<Props, object> {
    
        constructor(props: Props) {
            super(props);
        }
    
        render() {
            const { name, points, onIncrement, onDecrement } = this.props;
    
            return (
                <div className="hello">
                    <div className="greeting">
                        Hello {name + points}
                    </div>
                    <button onClick={onDecrement}>-</button>
                    <button onClick={onIncrement}>+</button>
                </div>
            );
        }
    }
    
    export default Points;
    

    容器:

    export function mapStateToProps({ points, languageName }: StoreState) {
        return {
            points: points,
            name: languageName,
        }
    }
    
    export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>) {
        return {
            onIncrement: () => dispatch(actions.incrementEnthusiasm()),
            onDecrement: () => dispatch(actions.decrementEnthusiasm())
        }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(Points);
    

    存储状态:

    export interface StoreState {
        languageName: string;
        points: number;
        food: number;
        wood: number;
    }
    

    当进行建议的更改(更换减速器和组合收割机时,我会得到一个新的错误:

    enter image description here

    我的减速器现在看起来像:

    export function pointReducer(state: 1, action: EnthusiasmAction) {
        switch (action.type) {
            case INCREMENT_ENTHUSIASM:
                return state + 1;
            case DECREMENT_ENTHUSIASM:
                return Math.max(1, state - 1);
            case GAME_TICK:
                return state + 1;
            default:
                return state;
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   markerikson    7 年前

    问题可能在于你如何使用 combineReducers ,与你的写作方式 mapState 功能。

    我想你的 地图状态 函数如下:

    const mapState = (state) => {
        return {
            points : state.points
        }
    }
    

    当你使用你的 pointsReducer 因为你的国家 state.points .

    但是,当你使用 组合器 就你现在的情况而言,你为自己制造了两个问题:

    • 你在命名州域 state.pointsReducer 不是 状态点
    • 你的 点减速器 将数据进一步嵌套为 points

    因此,您需要的实际数据位于 state.pointsReducer.points ,当组件在 状态点 .

    要解决这个问题,你应该改变你打电话的方式 组合器 ,并更改 点减速器 定义只跟踪数据而不嵌套:

    export function pointReducer(state: 1, action: EnthusiasmAction): StoreState {
        switch (action.type) {
            case INCREMENT_ENTHUSIASM:
                return state + 1
            case DECREMENT_ENTHUSIASM:
                return Math.max(1, state - 1);
            case GAME_TICK:
                return state.points + 1;
            default:
                return state;
        }
    }
    
    // later
    
    const rootReducer = combineReducers({
        points : pointsReducer,
        languageName : languageNameReducer,
    });
    

    Redux docs page on "Using combineReducers " 有关详细信息

    推荐文章