Redux 在存储中返回一个空数组 - Reducer 无法正常工作?

Jam*_*Gee 5 arrays json reactjs redux redux-thunk

我最近第一次将 Redux 放入我的应用程序中,并认为我可以正常工作,但它似乎返回了空数组。我检查了我的 Postman get 帖子,它在后端工作正常。如果数组为空,我的商店是否应该返回值,如下所示?

大概是什么问题?我有一个异步 Thunk 动作创建器和一个我认为工作正常的创建切片 Reducer。

如果我的 createSlice 索引 combineReducers 都显示为白色,这是否意味着它们无法正常工作?auth 和 message 是黄色的,我的登录工作正常,但是我没有为它们使用 createSlice。

更新:我认为这与我的 extraReducers “state: actionpayload.field”的语法有关。没有错误消息标记,但我不确定它是否在做它应该做的事情。

或者这可能与我的商店有一个 combineReducer 并通过 createSlice 的 reducer 的事实有关?(应该是 Redux 工具包的 configureStore)我的身份验证和消息工作正常,但它们不是 Redux。configureStore 是否同时允许 createSlice 和普通 switch 语句?

索引.js

export default combineReducers({

    // combine the reducers
                user,
                fields,
                article,
                diveLog,
                marineList,
                diveSchool,
                diveSpot,
                admin,
                auth,
                message
});
Run Code Online (Sandbox Code Playgroud)

减速器

const fieldsSlice = createSlice({
    name: 'diveLogFields',
    initialState: {
        current: [],
        region: [],
        diveType: [],
        visibility: [],
        diveSpot: [],
    },
    reducers: {},
    extraReducers: {
        // picks up the success action from the thunk
        [requireFieldData.fulfilled.type]: (state, action) => {
            // set the property based on the field property in the action
            (state: action.payload.field); (state: action.payload.items)
        }
    }
})
export default fieldsSlice.reducer;
Run Code Online (Sandbox Code Playgroud)

行动

export const requireFieldData = createAsyncThunk(
    'fields/requireData', // action name
    // action expects to be called with the name of the field
    async (fields) => {
        // you need to define a function to fetch the data by field name
        const response = await diveLogFields(fields);
        const { data } = response;
        // what we return will be the action payload
        return {
            fields,
            items: data.data
        };
    },
    // only fetch when needed
    {
        condition: (fields, {getState}) => {
            const {field} = getState();
            // check if there is already data by looking at the array length
            if ( field[fields].length > 0 ) {
                // return false to cancel execution
                return false;
            }
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

更新

当我尝试呈现我的页面时,我仍然收到以下错误消息。我不得不进入我的商店并添加 compose Redux 导入。

此消息表明问题出在哪里?

在此处输入图片说明

在此处输入图片说明

Aje*_*hah 4

我在您的代码中发现了一些小问题,因此,以下是修复和说明:

片:

const fieldsSlice = createSlice({
  name: 'diveLogFields',
  initialState: {
    current: [],
    region: [],
    diveType: [],
    visibility: [],
    diveSpot: [],
    fields: [], // Add initial fields array (if you want to store it)
    items: [], // Add initial items array (if you want to store it)
  },
  reducers: {},
  extraReducers: {
    [requireFieldData.fulfilled.type]: (state, action) => {
      state.fields = action.payload.fields
      state.items = action.payload.items
    },
  },
})
export default fieldsSlice.reducer
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,您可以使用state.fields = ...state.items = ...来设置状态中的数据。看起来我们正在直接改变状态,但我们并不是因为......

Redux Toolkit 允许我们在减速器中编写“变异”逻辑。它实际上并没有改变状态,因为它使用 Immer 库,该库检测“草稿状态”的更改并根据这些更改生成一个全新的不可变状态

异步ThunkAction:

// Assumption, fake async call
function diveLogFields(fields) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ data: { data: [1, 2, 3] }, fields })
    }, 2000)
  })
}

export const requireFieldData = createAsyncThunk(
  'diveLogFields/requireFieldData',
  async (fields) => {
    const response = await diveLogFields(fields)
    const { data } = response
    return {
      fields,
      items: data.data,
    }
  },
  {
    condition: (fields, { getState, extra }) => {
      const { fields: fieldsState } = getState() // getState() returns your Redux State
      if (fieldsState.fields.length > 0) {
        return false // cancel the action if fields has some data
      }
    },
  }
)
Run Code Online (Sandbox Code Playgroud)

以下是调度异步操作的示例:

function MyComponent() {
  const dispatch = useDispatch()

  // for example, make async call below hook
  useEffect(() => {
    dispatch(requireFieldData([4, 5, 6]))
  }, [dispatch])

  return (
    <>i am MyComponent</>
  )
}
Run Code Online (Sandbox Code Playgroud)

现在,这是调度操作后状态的样子:

还原状态