【问题标题】:How to show array of objects with useSelector?如何使用 useSelector 显示对象数组?
【发布时间】:2021-09-29 12:41:07
【问题描述】:

我应该使用什么来代替useSelectormapStateToProps?这些运行多次(array.lenght)并将所有值更改为最后一个。

我有一个电子商务应用, ProductDetails 组件包含产品评论,我将它们映射到 ProductReview 组件以获取从用户 ID 获取的用户信息。

ProductDetails.js

import React, { useEffect } from "react";
import ProductReview from "../components/ProductReview";
import { useSelector, useDispatch } from 'react-redux';
import { getProductDetailsById } from "../Store/actions/productActions";

export default function ProductDetails(props) {
    const dispatch = useDispatch()
    const product = useSelector((state) => state.product)

  useEffect(() => {
    const { id } = props.match.params;
    const payload = {
      params: {
        id,
      },
    };
    dispatch(getProductDetailsById(payload));
    
  },[dispatch, props.match.params]);

  return (
    <div>
      {product.productDetails.reviews && 
        product.productDetails.reviews.map((item , index) =>    
        (
           <li key={item.userId}>
              <ProductReview key={item.userId} userId={item.userId} 
                             review={item.review}/>
           </li> )
               )}
        )}
</div>
  );
}

ProductReview.js


import React,{ useState, useEffect } from 'react';
import { getUSerById } from '../Store/actions/userAction';
import {useDispatch , useSelector} from 'react-redux';

export default function ProductReview(props) {
  const dispatch = useDispatch()
  const user = useSelector(state => state.user)
  
const {userId} = props;
  
  useEffect(() => {
    const payload = {
      params : {
        userId
      }
    }
    dispatch(getUSerById(payload))  
  },[userId]);

    
 return (
    <div>
        {user && user.user.firstName} : {props.review}
    </div>
  )
}

这部分代码运行多次并且 将所有用户信息值(用户名)更改为最后一个。 **所有产品评论firstNames 更改为最后一条**同名

  const user = useSelector(state => state.user)

有什么办法可以解决这个问题吗? 它当前在ProductReview 组件中使用Axios 和useState() 时运行,但我想使用redux。

userReducer.js

import { userConstants } from "../actions/Types";

const initState = {
  user: {},
  loading: false,
  error: null
};

export default (state = initState, action) => {
  console.log(action.payload)
  switch(action.type){
    case userConstants.GET_USER_BY_ID_SUCCESS:
      return state = {
        ...state,
        user : action.payload.user,
        loading: false,
        error: null
      }
    case userConstants.GET_USER_BY_ID_FAILURE:
      return state = {
        state,
        error: action.payload.error
      }  
    default:
      return state
  }
}

【问题讨论】:

  • 您忘记在 ProductReview 的 useEffect 依赖项中添加 userId
  • 我不明白这里发生了什么。如果你用getUSerById 更新redux store 中的state.user,那么选择器const user = useSelector(state =&gt; state.user) 返回最后一个用户的值是正常的。你想达到什么目标?
  • 你可以用什么来代替useSelectormapStateToProps?好吧,我想您可以通过 store 对象直接访问 redux 状态,但通常建议这样做。除此之外,有点不清楚问题是什么。对于您在ProductDetails 中映射的内容,您向每个元素发送相同的userId 作为道具,所以我希望所有ProductReview 组件都具有相同的道具值。
  • @MarcoNisi 所有评论都返回相同的名字(最后一个)。但他们应该有不同的名字。
  • 分享你的减速器逻辑。

标签: javascript node.js reactjs redux mern


【解决方案1】:

还有一个选择。但就像那两个一样,这也会运行多次。但无论如何我都会分享它:

var client;
store.subscribe(() => {
  client = store.getState().client;
});

将这段代码放在你的组件之上,赋予它全局作用域,使这个客户端变量在你的组件中是可访问的。每次更改 store 时,subscribe 方法都会读入其中并导致其中的功能呈现,这导致 getState() 函数获取存储在 store 中的状态的客户端部分。现在,您可以在组件中使用一个变量,该变量将在商店更改时更新。

【讨论】:

  • 谢谢,但我想我应该改变我的问题。
【解决方案2】:

根据我在 cmets 中的理解,您需要以某种方式将所有用户存储在您的 redux 存储中。 例如,您可以执行以下操作:

  1. initState 更改为:

    const initState = {
      users: {},
      loading: false,
      error: null
    };
    
  2. GET_USER_BY_ID_SUCCESS减速机改成 (请注意我使用的是user.id,但可能您的 id 存储在其他属性中):

    case userConstants.GET_USER_BY_ID_SUCCESS:
      return state = {
        ...state,
        users: { ...state.users, [action.payload.user.id]: action.payload.user },
        loading: false,
        error: null
      }
    
  3. 将 useSelector 更改为:

    const users = useSelector(state => state.users)
    
  4. 添加:

    const user = users[props.userId]
    

通过这种方式,您应该拥有正确的用户。如果我错过了什么,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2019-02-27
    • 1970-01-01
    • 2017-04-07
    • 2020-11-08
    • 2019-06-13
    相关资源
    最近更新 更多