开发者问题收集

努力从 Redux Store 获取数组数据

2021-09-08
967

我无法访问使用 redux 检索的数组中的项。当我在操作本身中执行控制台日志时,我可以单独访问数组元素。但是,一旦该数据在操作分派后进入组件进行显示,我就无法正确解析数据结构。

ListingActions.js: 如果我在此处执行控制台日志,我可以毫无问题地解析变量数据的不同索引

export const getListings = () => async (dispatch) => {
try {
    dispatch({ type: LISTING_REQUEST })

    const { data } = await axios.get('/gmk')
    // I can access the elements of the array here without a problem

    dispatch({ type: LISTING_SUCCESS, payload: data })
} catch (error) {
    dispatch({
        type: LISTING_FAIL,
        payload: error.response && error.response.data.message ? error.response.data.message : error.message,
    })
}

ListingReducers.js:

export const listingReducer = (state = { itemListings: [] }, action) => {
switch (action.type) {
    case LISTING_REQUEST:
        return { loading: true, itemListings: [] }
    case LISTING_SUCCESS:
        return { loading: false, itemListings: action.payload }
    case LISTING_FAIL:
        return { loading: false, error: action.payload }
    default:
        return state
}

来自 store.js 的代码片段:

const initialState = {
itemListings: [],
nope: { nopeItems: nopeItemsFromStorage },
keep: { keepItems: keepItemsFromStorage },

HomeScreen.js:

function HomeScreen() {
const dispatch = useDispatch()

const freshItemListings = useSelector((state) => state.itemListings)
const { loading, error, itemListings } = freshItemListings

useEffect(() => {
    dispatch(getListings())
}, [dispatch])

return <div>{loading ? <p>Loading</p> : error ? <p>{error}</p> : itemListings.length}</div>

您会看到我正试图访问 itemListings 的长度。当我这样做时,我收到一个错误:TypeError:无法读取未定义的属性(读取“长度”)。我做了其他事情,比如 itemListings[0],以及其他方法,只是为了看看我的选择是什么,但每个都导致了错误。

3个回答

我认为这与您在 ListingReducers.js 中更新 itemListings 的方式有关。

case LISTING_SUCCESS:
        return { loading: false, itemListings: action.payload }

您必须使用扩展 (...) 运算符更新 itemListing 以保留 此处 所述的当前 状态

case LISTING_SUCCESS:
        return { 
           ...state,
           loading: false,
           itemListings: action.payload
       }

在您的代码中,初始状态实际上从未在您的 Reducer 中更新。

请参阅 Redux 文档

They are not allowed to modify the existing state. Instead, they must make immutable updates, by copying the existing state and making changes to the copied values.

WARNING In Redux, our reducers are never allowed to mutate the original / current state values!

// ❌ Illegal - by default, this will mutate the state!
state.value = 123

TIP Reducers can only make copies of the original values, and then they can mutate the copies.

// ✅ This is safe, because we made a copy
return {
  ...state,
  value: 123
}
Parker Pfaff
2021-09-09

目前,您的应用中有两个 itemListings ,我认为这会造成一些混淆。

在这里:

    const initialState = {
itemListings: [],
nope: { nopeItems: nopeItemsFromStorage },
keep: { keepItems: keepItemsFromStorage },

商店中的默认 itemListings 状态是一个数组。

然后在这里:

const freshItemListings = useSelector((state) => state.itemListings)

freshItemListings 是相同的数组,您正在组件中接收它

然后在此行中:

const { loading, error, itemListings } = freshItemListings

您正在从数组中提取 itemListings 属性 ,这会导致错误。

您必须在初始状态下将 itemListings 定义为对象:

     const initialState = {
itemListings: {itemListings:[]},
nope: { nopeItems: nopeItemsFromStorage },
keep: { keepItems: keepItemsFromStorage },

另一个解决方案是您已经在其 Reducer 中为 itemListings 定义初始状态,省略 initialState 对象中的 itemListings 属性,

         const initialState = {
nope: { nopeItems: nopeItemsFromStorage },
keep: { keepItems: keepItemsFromStorage },
Erfan
2021-09-09

我发现问题在于如何正确设置我的商店中的初始状态。我确实按照建议更改了一些变量名称,以便更容易阅读。

对 store.js 的更改:

const initialState = {
listingData: { itemListings: [], loading: true },
nope: { nopeItems: nopeItemsFromStorage },
keep: { keepItems: keepItemsFromStorage },

将加载和 itemListing 部分都设置为正确的初始状态最终是答案。

Amateur Production
2021-09-12