无法在状态较少的组件reactjs中获取更新redux状态

时间:2018-10-25 12:07:15

标签: javascript reactjs redux react-redux redux-thunk

在我的reactJs应用中,我使用的是redux-thunk,当我更新redux状态时,我的无状态组件没有获得更新的状态值。
我的 Addons.js

import React from 'react';
import {connect} from 'react-redux';
import {addOnSelected, addonsCount, updateVehData} from '../../actions'
import { Card,Row,Col,Avatar } from 'antd';
import { Collapse} from 'antd';
const Panel = Collapse.Panel;
import HelperImg from '../../../public/images/Helper.png'

const Addons = (props)=>{
    console.log(props.VehcileData,"asd")
    let addonsCards = [];

    const addonsCard = (addon)=>{
        addonsCards.push(
            <Col lg={{span:7,offset:1}} key={addon.text} style={{paddingBottom:'2rem'}}>
            <Card
            type="inner"
            // title="Small Vehicle"
            id='addonCard'
            hoverable
            onClick={(e)=>{(e.target.id !== 'minus' && e.target.id !== 'adQty' && e.target.id !== 'plus') && props.updateVehData(addon) }}
            className={`${addon.selected ? 'addSelected' :''} ad_card`}
        >
            <Row type="flex" justify="space-around" align="middle" gutter={16}>
                <Col lg={{span:16}} xs={{span:24}} style={{padding:'0px'}} >
                    <div className='ad_img' align='middle'>
                        <Avatar src={HelperImg} />
                    </div>
                    <div align='middle'>
                    <h3 className='ad_title'>{addon.text}</h3>
                    </div>
                </Col>
                <Col lg={{span:16,offset:5}} xs={{span:16,offset:5}}>
                    <div className="input-group">
                        <input type="button" value=" - " id='minus' className="button-minus" onClick={()=>props.addonsCount(addon)}/>
                        <input type="number"  className="quantity-field" id='adQty'/>
                        <input type="button" value="+" className="button-plus" id="plus"/>
                    </div>
                </Col>
                <Col lg={{span:24}} xs={{span:24}} className='price'>
                    <div className='ad_price'>
                        <h3>Price RS 2000</h3>
                    </div>
                </Col>
            </Row>

        </Card>
        </Col>)
    }
    const loopVData =()=>{
        for (const key of Object.keys(props.VehcileData)) {
            if(props.VehcileData[key].vid === props.VSelected){
                props.VehcileData[key].mand.map((addon,i)=>{
                    addonsCard(addon)
                })
                props.VehcileData[key].pre.map((addon,i)=>{
                    addonsCard(addon)
                })

                props.VehcileData[key].optn.map((addon,i)=>{
                    addonsCard(addon)
                })
            }
        }
    }
    return(
        <div>
            <Collapse defaultActiveKey={['1','2']} >
            <Panel header="SELECT ADDONS" key="1">
                <Row >

                    {loopVData()}
                    {addonsCards}
                </Row>
            </Panel>
            </Collapse>
        </div>
    )
}


const mapStateToProps = (state) =>{
    console.log(state.StepThreeReducer.vehcileData)
    return{
        VehcileData:state.StepThreeReducer.vehcileData,
        VSelected:state.StepThreeReducer.isAmbSel
    }
}
export default connect(mapStateToProps,{addOnSelected,addonsCount,updateVehData})(Addons);

我的 ACTION.js

export function updateVehData(val){
    return function(dispatch,getState){
        if(val.type === 'opt'){
            let VehData = getState().StepThreeReducer.vehcileData;
            let vehID =getState().StepThreeReducer.isAmbSel;            
            for (const key of Object.keys(VehData)) {
                // console.log(VehData[key])
                if(VehData[key].vid === vehID){
                    VehData[key].optn.forEach(addon=>{
                        if(addon._id==val._id){
                            addon.selected = !addon.selected;
                            if(addon.selected === true){
                                addon.qty=1;
                            }else if(addon.selected === true){
                                addon.qty=0;
                            }
                        }
                    });

                }
            }
            dispatch({type:VEHICLEDATA,payload:VehData})
        }
    }
}

我的 Reducer.js

import {ISAMBSEL,ADDONSEL,TOTALPRICE,VEHICLEDATA} from '../actions/types';
const INITIAL_STATE = {
    isAmbSel:null,
    addonSel:[],
    vehcileData:0,

};
export default  (state=INITIAL_STATE,action) => {
    // console.log(action,'reducer')
    switch(action.type) {
        case ISAMBSEL:
            return {...state,isAmbSel:action.payload};
        case ADDONSEL:
            return {...state,addonSel:[...action.payload]}
        case TOTALPRICE:
            return {...state,totalPrice:action.payload}
        case VEHICLEDATA:{
            return {...state,vehcileData:action.payload}}
        default:
            return state;
    }
}

在我的mapStateToProps函数中,如果我管理state.StepThreeReducer.vehcileData,我将获得更新的值,但是当我在 Addons 组件中进行价值管理时,它不会显示{{1} }值,即使在更新redux状态后,它也不会呈现
,但是如果我通过父组件将更新后的状态值发送给我的,则其父组件正在显示更新后的redux状态值插件组件,那么它也不会显示redux状态的更新值。
我认为我在 Actions (操作)或 Reducer (还原器)中没有任何问题,因为在props.VehcileData中它显示了实时Redux状态值。

1 个答案:

答案 0 :(得分:2)

let VehData = getState().StepThreeReducer.vehcileData;
let vehID = getState().StepThreeReducer.isAmbSel;
for (const key of Object.keys(VehData)) {
  // console.log(VehData[key])
  if (VehData[key].vid === vehID) {
    VehData[key].optn.forEach(addon => {
      if (addon._id == val._id) {
        addon.selected = !addon.selected;
        if (addon.selected === true) {
          addon.qty = 1; // <-- mutating
        } else if (addon.selected === true) {
          addon.qty = 0; // <-- mutating
        }
      }
    });
  }
}

当mapStateToProps被调用时,它将检查您的prevStatenextState的黑白差异,以便它可以确定是否需要更新组件

您的情况是,您仅在此处改变状态,并且在reducer中进行更新后,prevState与您在reducer中进行更新的情况相同。

您应该尝试对其进行深度克隆或更改程序。

  

您还应该在还原中使用middleware (redux-immutable-state-invariant) which will detect mutation并引发警告。