更新:没有调用 Redux reducer 来更改 CSS 类

Posted

技术标签:

【中文标题】更新:没有调用 Redux reducer 来更改 CSS 类【英文标题】:Update: Redux reducer is not beeing called to change CSS classes 【发布时间】: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 我已经尝试过这种方式,但结果相同。减速器现在看起来像这样。但还是什么都没有 【参考方案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 方法移到了选择器中。

【讨论】:

以上是关于更新:没有调用 Redux reducer 来更改 CSS 类的主要内容,如果未能解决你的问题,请参考以下文章

React,redux 组件不会在路由更改时更新

Redux 入门

Redux状态更新后没有调用ComponentDidMount?

从 redux 更改状态后如何以及何时调用反应组件方法

React-native 和 Redux 健康的方式来调用 props 更改的操作

React Redux 表更新行