React Native Redux-从预填充的数据分配状态属性

时间:2018-06-25 22:36:11

标签: react-native redux

我是Redux和React Native的新手,所以如果我犯了一个明显的错误,我深表歉意。

在我遇到遇到的错误之前,这里有一些背景知识。

我有一个状态和一个数据库(SQLite)。我有一个实例,需要在其中擦除状态并从数据库中重新填充状态。我已经从数据库中收集并解析了数据,只需要将其添加到状态中即可。

Specifics:我在数据库中有一个对象列表(我们称汽车),每个对象都有自己的属性。我创建了汽车列表,并通过了该列表。收到后,我将创建一个“伪状态”(只是空的初始状态),并通过添加汽车列表来对其进行更改,因为我知道您不应该更改实际状态。

然后我尝试使用新车属性返回状态。

我收到一条错误消息:TypeError:assign的来源之一在原型链上有一个可枚举的密钥。您是否要分配原型属性?我们不允许这样做,因为这是我们不支持的极端情况。该错误是性能优化,不符合规范。

我是否理解这个意思是说我无法像我想的那样分配redux状态属性?

const initialState = {
  cars: [],
  selectedDevice: null,
};

const getNewCarList = async (previousState) => {
  const carList = await DBProvider.callQueryDB();

  const carListLength = carList.length;
  let newState = previousState;

  for (let i = 0; i < carListLength; i += 1) {
    newState = {
      ...newState,
      cars: newState.car.concat({
        carName: carList[i].carName,
        carID: carList[i].carID,
      }),
    };
  }
  return newState;
};


const refreshStore = async (state = initialState, action) => {
  switch (action.type) {
    case REFRESH_STORE: {
      const newCarState = await getNewCarList(initialState).then(newState => newState);

      return {
        ...state,
        car: newCarState.cars,
      };
    }

    default:
      return state;
  }
};

1 个答案:

答案 0 :(得分:0)

搜索该错误消息会弹出this SO question,它链接到https://github.com/facebook/react-native/issues/16814。看来,这是特定于React Native的问题,是您的API调用和使用spread运算符的组合。

除此之外,您的代码还有两个主要问题:

  • 您正在用减速器进行异步调用,这是您永远都不应做的
  • 可以简化API响应中列表的处理

我建议按照以下方式重新设计您的逻辑:

// Handle the request in a thunk function
function getNewCarList() {
     return async (dispatch) => {
         const carList = await DBProvider.callQueryDB();

         // dispatch an action containing the cars array
         dispatch({
             type : "REFRESH_STORE",
             payload : {
                 cars : carList
             }
         });
     }
}

function carsReducer(state = initialState, action) {
    switch(action.type) {
        case "REFRESH_STORE" : {
            // the reducer just returns a new state value with the new array
            return {
                ...state,
                cars : action.payload.cars
            }
        }
        default : return state;
    } 
}