【问题标题】:Update: Redux reducer is not beeing called to change CSS classes更新:没有调用 Redux reducer 来更改 CSS 类
【发布时间】:2022-01-08 13:13:52
【问题描述】:

我是 redux 和 react-redux 的新手。
当用户单击动态呈现的<div> 标记时,我正在尝试更改 CSS 类。当我尝试在本地设置状态时,代码正在工作,但是当我想使用 redux 时,我得到了应该存储event.target.id 的数组的未定义值。你能告诉我我哪里错了吗? 我将从行动开始:

export const selectAttr = (e)=>{     
    return (dispatch) => {
        return(
            dispatch({
                type: SELECT_ATTRIBUTES,
                payload: e.target.id
            })
        )
    }
}

减速机:

 const initialState = {
    selectedAttr: [],
}
 

export default function selectAttrReducer (state = initialState, action) {
    let tmp = [...state.selectedAttr]
    function attributes() {
        if (tmp.length === 0) {
            tmp = [...tmp, action.payload];
            return tmp;
        } else {
            for (let i = 0; i < tmp.length; i++) {
                if (action.payload.split(":")[0] === tmp[i].split(":")[0]) {
                    tmp = [...tmp.filter(el => el.split(":")[0] !== action.payload.split(":")[0]), action.payload];

                } else {
                    tmp = [...tmp, action.payload];
                }
            }
            return tmp;
        }
    }
    switch(action.type){
        case SELECT_ATTRIBUTES:
           attributes()
            return {
                ...state,
                selectedAttr: [...state.selectedAttr, ...tmp]
            }
        default:
            return state    
    }
}

JSX 的片段:

<div>
    {attributes.map((attr, index) => (
        <div key={attr.id}>
            {/* attribute name */}
            <p className="pdp-attr">{attr.name}:</p>

            {/* attribute representation */}
            <div className="swatch-flex">
                {attributes[index].items.map((item) => (
                    <div key={item.id}>
                        <div
                            onClick={this.props.selectAttr}
                            className={
                                selectedAttr?.indexOf(
                                    attributes[index].id.concat(":", item.id)
                                ) === -1
                                    ? "pdp-box"
                                    : "pdp-box isSelected"
                            }
                            id={attributes[index].id.concat(":", item.id)}></div>
                    </div>
                ))}
            </div>
        </div>
    ))}
</div>

const mapStateToProps = (state) => {
    return {
        selectedAttr: state.selectedAttr,
    };
};

export default connect(mapStateToProps, { selectAttr })(Component);

更新:
看起来像调用了 reducer,但 selectedAttr 数组有数千个项目。我也更新了代码。
我也在使用redux-persist。可以,就因为这个?

【问题讨论】:

  • return {...state, ...tmp} Idk 将一个数组和一个对象散布在一起会做什么,但我敢打赌这不是你的本意。 tmp 是一个列表,而 state 是一个对象。我也担心你的减速器之外有状态。减速器几乎总是状态+动作的函数。将 tmp 拉入函数的本地范围。
  • 如果我将 tmp 带入函数 throws 中,“'tmp' is not defined” ` ({ ...state.selectedAttr, ...tmp})` 。我检查了整个应用程序,reducer 之外没有任何状态
  • let tmp = [...initialState.selectedAttr] 没有理由这不起作用
  • @nlta 我已经尝试过这种方式,但结果相同。减速器现在看起来像这样。但还是什么都没有

标签: javascript arrays reactjs redux react-redux


【解决方案1】:

你确定没有调用减速器吗?

这段代码有误:

return {
    ...state, ...tmp
}

(不要)*试试这个: 请参阅@nlta 的评论。

// must wrap in parenthesis to return an object
return ({
    ...state, ...tmp
})

【讨论】:

  • 我有一个 console.log(e.target.id) 正在运行,每次点击它都会记录下来。我还记录了该组件的道具,并且 selectedAttr 未定义。我将代码更改为return ({ ...state.selectedAttr, ...tmp }),它是一样的。它呈现为默认选择所有 div 标签
【解决方案2】:

reducer 被调用,但因为它是一个“纯”函数,(Rules of reducers) 我将 filter 方法移到了选择器中。

【讨论】:

    猜你喜欢
    • 2018-09-27
    • 2018-10-02
    • 2020-05-23
    • 2019-07-28
    • 2018-08-04
    • 1970-01-01
    • 2019-12-05
    • 2019-02-25
    • 2018-07-26
    相关资源
    最近更新 更多