Reactjs 无法更新我的应用程序的状态,reducer中的console.log显示对象已更改,但状态保持不变

Reactjs 无法更新我的应用程序的状态,reducer中的console.log显示对象已更改,但状态保持不变,reactjs,redux,react-redux,Reactjs,Redux,React Redux,玩redux让我很困惑。有些人认为,仅仅更新对象中一个键的状态变得如此困难 当用户选中组件内部的复选框时,将调度一个操作。检查后,产品的状态应从新变为保留: //ProductRow.js const ProductRow = React.createClass({ propTypes: { item: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired }, render () {

玩redux让我很困惑。有些人认为,仅仅更新对象中一个键的状态变得如此困难

当用户选中组件内部的复选框时,将调度一个操作。检查后,产品的状态应从新变为保留:

//ProductRow.js

const ProductRow = React.createClass({
  propTypes: {
    item: PropTypes.object.isRequired,
    onChange: PropTypes.func.isRequired
  },

  render () {
    const { code, name, imageUrl, description } = this.props.item.product
    const {status} = this.props.item
    const {onChange} = this.props
    return (
      <div>
        <label htmlFor={code}>
          <input type='checkbox' id={code} onClick={onChange} value={status} />
          <img src={imageUrl} />
          <div className='name'>{name}</div>
          <div className='description'>{description}</div>
        </label>
      </div>
    )
  }
})

如果更改状态的一部分,则需要为状态创建新的对象引用。按照您这样做的方式,您的旧状态仍将===您的新状态,因此redux无法知道它已更改

此外,setStatusToReserved函数根本不返回任何内容

你们的州不应该像现在这样嵌套得很深,我认为还有更多的工作要做,但向前迈出的一步是:

const setStatusToReserved = (state, action) => {
  const {items} = state.shoppingCartData.data

  const newItems = items.map(item => {
    if(action.item.id === item.id) {
      console.log(Object.assign({},action.item, {status: 'RESERVED'}))
      return Object.assign({}, action.item, {status: 'RESERVED'})
    }
  })

  return {
    ...state,
    shoppingCartData: {
      ...shoppingCartData.data,
      items: newItems
    }
  }
}

我强烈建议观看免费的,并解决所有这些问题。

我简化了减速器,我只通过设置我要更改的初始状态,并将产品列表设置为我的智能组件,从商店获取状态,因为这是我唯一希望更改状态的组件。我认为我对减速机所做的更改和小心地拿起我的智能组件起到了帮助。谢谢你的视频推荐,丹的视频帮了大忙

import { ACTIONS } from './actions'

/**
 * Returns an updated array with check product status set to RESERVED
 * @param state
 * @param action
 * @return {[*,*,*]}
 */
const setStatusToReserved = (state, action) => {
  let updateStatus = Object.assign({}, action.item, {status: 'RESERVED'})
  let index = state.indexOf(action.item)

  return [...state.slice(0, index), updateStatus, ...state.slice(index + 1)]
}

/**
 * Returns an updated array with check product status set to NEW
 * @param state
 * @param action
 * @return {[*,*,*]}
 */
const setStatusToNew = (state, action) => {
  let updateStatus = Object.assign({}, action.item, {status: 'NEW'})
  let index = state.indexOf(action.item)

  return [...state.slice(0, index), updateStatus, ...state.slice(index + 1)]
}

/**
 * Function that takes the current state and action and return new state
 * Initial state is set to product items
 * @param state
 * @param action
 * @return {{}}
 */
const rootReducer = (state = {}, action) => {
  switch (action.type) {
    case ACTIONS.SET_STATUS_TO_RESERVED:
      return setStatusToReserved(state, action)

    case ACTIONS.SET_STATUS_TO_NEW:
      return setStatusToNew(state, action)

    default:
      return state
  }
}

export default rootReducer

从您的示例代码来看,似乎还没有连接mapStateToProps。这就是如何将修改从redux导入组件的方法。你可以从这里开始阅读:谢谢安迪,你说得对,我把事情弄得复杂多了。我有一个bigdata.json文件,用作默认的_状态并传递给所有组件。我认为这是个坏主意,因为我的许多组件都使用静态数据。只有产品项需要双向绑定。您认为我最好将其余数据传递给我导入data.json并作为道具传递,并仅将ProductList连接到redux?在顶级状态对象中,每个键都是一个reducer控制或嵌套reducer控制的特定状态片。我建议你看视频。Stackoverflow不适用于来回类型的问题。如果这回答了您的问题,请单击它旁边的空复选标记将其标记为正确。如果没有,你能完善这个问题吗?嘿,安迪,谢谢视频,真的帮了我的忙,我把初始状态传递给了商店,我想改变的状态。其余的我通过道具传递。
const setStatusToReserved = (state, action) => {
  const {items} = state.shoppingCartData.data

  const newItems = items.map(item => {
    if(action.item.id === item.id) {
      console.log(Object.assign({},action.item, {status: 'RESERVED'}))
      return Object.assign({}, action.item, {status: 'RESERVED'})
    }
  })

  return {
    ...state,
    shoppingCartData: {
      ...shoppingCartData.data,
      items: newItems
    }
  }
}
import { ACTIONS } from './actions'

/**
 * Returns an updated array with check product status set to RESERVED
 * @param state
 * @param action
 * @return {[*,*,*]}
 */
const setStatusToReserved = (state, action) => {
  let updateStatus = Object.assign({}, action.item, {status: 'RESERVED'})
  let index = state.indexOf(action.item)

  return [...state.slice(0, index), updateStatus, ...state.slice(index + 1)]
}

/**
 * Returns an updated array with check product status set to NEW
 * @param state
 * @param action
 * @return {[*,*,*]}
 */
const setStatusToNew = (state, action) => {
  let updateStatus = Object.assign({}, action.item, {status: 'NEW'})
  let index = state.indexOf(action.item)

  return [...state.slice(0, index), updateStatus, ...state.slice(index + 1)]
}

/**
 * Function that takes the current state and action and return new state
 * Initial state is set to product items
 * @param state
 * @param action
 * @return {{}}
 */
const rootReducer = (state = {}, action) => {
  switch (action.type) {
    case ACTIONS.SET_STATUS_TO_RESERVED:
      return setStatusToReserved(state, action)

    case ACTIONS.SET_STATUS_TO_NEW:
      return setStatusToNew(state, action)

    default:
      return state
  }
}

export default rootReducer
[PROD_FORM_DETAILS_SUCCESS]: (state, { payload: { ProdDetailsData } }) => 
        {
            console.log(" reducer ===================== " , catalogueProductDetailsData);
        return {
      ...state,
      catalogueProductDetailsData,
      isFetching: false,
    }},

[CREATE_USER_FORM]: (state, {}) => {
      console.log(" reducer =======CREATE_USER_FORM ============== ");
      return {
        ...state,
        isFetching: false,
      };
    },

   //Without console

    [CREATE_USER_FORM]: (state, {}) => ({
      ...state,
      isFetching: true,
    }),