努力从 Redux Store 获取数组数据

Struggling to Get Array Data From Redux Store

我无法访问我正在使用 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:无法读取未定义的属性(读取 'length')。我已经做了其他事情,比如 itemListings[0],以及其他方法只是为了看看我的选择是什么,但每一个都导致了错误。

我认为这与您在 ListingReducers.js

中更新 itemListings 的方式有关
case LISTING_SUCCESS:
        return { loading: false, itemListings: action.payload }

您必须使用扩展 (...) 运算符更新 itemListing 以保留当前的 ​​state 描述了 here.

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

在您的代码中,初始状态实际上从未在您的减速器中得到更新。

Redux Documentation

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
}

目前您的应用程序中有两个 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 },

另一种解决方案是因为您已经在其减速器中为 itemListings 定义了初始状态,因此在 initialState 对象中省略了 itemListings 属性,

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

我发现问题出在我的商店中正确设置初始状态。我确实按照建议更改了一些变量名称,以提高可读性。

对 store.js 的更改:

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

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