组件中仅呈现了一部分更新状态(React / Redux)

液体

我目前正在尝试与Redux结合使用React并遇到一个奇怪的问题:

如果状态的一个属性被更改,则视图将在组件中更新。如果另一个属性已更改,则不会更新-除非我再次更新第一个属性。我将尝试使其更加清晰:

这是商店界面:

export interface StoreState {
    counter: number;
    rectangles: Rectangle[];
}

这是减速器:

export function enthusiasm(state: StoreState, action: EnthusiasmAction): StoreState {
    switch (action.type) {
        case INCREMENT_ENTHUSIASM:
            return { ...state, counter: state.counter + 1 };
        case DECREMENT_ENTHUSIASM:
            return { ...state, counter: Math.max(1, state.counter - 1) };
        case ADD_RECTANGLE:
            let updatedRectangles: Rectangle[] = [];
            if(state.rectangles){
                updatedRectangles = state.rectangles;
            }
            updatedRectangles.unshift(action.payload);
            return {...state, rectangles: updatedRectangles};
        default:
            return state;
    }
}

这是包装组件的容器:

export function mapStateToProps(state: StoreState) {
    return {
        enthusiasmLevel: state.counter,
        rectangles:state.rectangles,
    }
}

export function mapDispatchToProps(dispatch: Dispatch<actions.EnthusiasmAction>) {
    return {
        onIncrement: () => dispatch(actions.incrementEnthusiasm()),
        onDecrement: () => dispatch(actions.decrementEnthusiasm()),
        addRectangle: () => dispatch(actions.addRectangle({posX: Math.floor(Math.random() * 100), posY: Math.floor(Math.random() * 100), id: Math.floor(Math.random() * 1000)}))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Hello);

这是我要渲染的组件:

function Hello({ counter = 1, rectangles = [], onIncrement, onDecrement, addRectangle }: Props) {
    console.log(counter, rectangles);
    return (
        <div className="hello">
                <button onClick={onDecrement}>-</button>
                <button onClick={onIncrement}>+</button>
                <button onClick={addRectangle}>+</button>
            <Stage width={window.innerWidth} height={window.innerHeight}>
                <Layer>
                    {
                        rectangles.map((rectangle: Rectangle) => {
                            return <Rect
                                key={rectangle.id}
                                x={rectangle.posX}
                                y={rectangle.posY}
                                width={150}
                                height={150}
                                fill={'green'}
                                draggable
                                onDragStart={handleDragStart}
                                onDragEnd={handleDragEnd}
                            />
                        })
                    }
                </Layer>
            </Stage>
        </div>
    );
}

当我增加计数器时,视图将更新并记录状态。

在此处输入图片说明

当我调用addRectangle时,即使状态已更改,视图也不会更新(并且状态未记录在组件中): 在此处输入图片说明

现在,当我再次增加计数器时,该视图最终将得到更新,并且之前添加的所有矩形都将添加到该视图中(并再次记录状态):

在此处输入图片说明

由于我是新来的反应者,因此问题似乎很明显,但是我无法弄清楚我做错了什么。非常感谢您的帮助,谢谢!

霍肯会员

您正在变异state.rectangles如果状态不变,则Redux会跳过渲染。您应该改为创建一个新数组。在redux文档中对此进行了解释:更新嵌套对象

常见错误#1:指向相同对象的新变量

定义新变量不会创建新的实际对象-只会创建对同一对象的另一个引用。

在这种情况下,我们的问题是这updatedReactangles不是一个新数组。

case ADD_RECTANGLE:
    let updatedRectangles: Rectangle[] = [];
    if(state.rectangles){
        updatedRectangles = state.rectangles;  // still the same array
    }
    updatedRectangles.unshift(action.payload);
    return {...state, rectangles: updatedRectangles};

尝试这样的事情:

case ADD_RECTANGLE:
    let updatedRectangles: Rectangle[] = [];
    if(state.rectangles){
        updatedRectangles = state.rectangles.slice();  // shallow copy
    }
    updatedRectangles.unshift(action.payload);
    return {...state, rectangles: updatedRectangles};

...运营商可以让这个错误更容易避免。由于没有诸如此类的变异方法Array.unshift(),因此我们可以确保我们不会无意间破坏了先前的状态。

case ADD_RECTANGLE:
  return {
    ...state, 
    rectangles: [...state.rectangles, action.payload],
  }

但是要确保它state.rectangles始终是一个数组,而不要undefined通过向reducer提供默认的初始状态参数来确保。

function reducer(state={ rectangles: [] }, action) {

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Promise 作为 redux 状态的一部分

如何在React应用程序中仅加载Redux存储的一部分

如何使用 redux-persist 仅存储一部分 redux 状态

使用 redux 和 react,为什么获取新数据会删除我以前状态的一部分?

NGRX Redux存储-即使智能感知自动完成并且模型中的所有内容都匹配,仅选择状态的一部分也会返回“未定义”

React - Redux 状态更新但未在组件中呈现

“state.set 不是函数”作为我的 react-redux-immutable 学习曲线的一部分

如何重置一部分 Redux,但保留其余部分?

如何将Redux存储的一部分转换为数组

如何检查泛型K是否为泛型M的一部分。打字稿通用 Redux

React + Redux更新状态未重新呈现

如何在组件B中呈现组件A的一部分

在 react-redux 中从父组件更新子组件的状态

react-redux 更新 redux 存储但不更新组件状态

如何从子组件仅更改状态的一部分反应钩子

如何仅更改状态的一部分?

React + Redux。Connect不会更新组件的状态

React-Redux 更新部分状态

React-Router Redirect仅渲染组件的一部分

如何下载 React 组件的一部分?

无法从redux接收react组件中的状态

状态更改后,react-redux组件未重新呈现

使用react-native的React-navigation:如果组件的一部分不呈现DrawerIcon

在 React.js 中:是否可以只访问子组件的一部分?

通过react JS中的函数渲染组件的一部分

如果仅更改组件的一部分,React会渲染该组件吗?

组件中的 Redux mapStateToProps 状态

如何更新 React Redux 中的状态?

从 React 中从 redux 读取的数据更新状态