首页 > 解决方案 > MERN Redux TypeError:conversations.map is not a function redux

问题描述

我有一个组件需要访问减速器中的状态。当我调用 useSelector 来获取状态时,起初它是一个空对象,然后大约 3 秒后,BAM 数据进来了。

我想对组件中的这些数据运行 .find 或 .map 以查看某些值是否匹配。

页面加载大约 3 秒,然后 bam,TypeError: conversations.map is not a function

这是我下面的组件

import React, { useState, useContext} from 'react';
import { TabContent, TabPane } from 'reactstrap';
import { useSelector } from 'react-redux';
import ChatContentHeader from './ChatContentHeader';
import MessageTextArea from './MessageTextArea';
import ChatContentBody from './ChatContentBody';
import { ChatContext } from '../../../context/Context';

const ChatContent = () => {
  
  const { threads, activeThreadId, selContact, activeConversationId, setSelContact } = useContext(ChatContext);
  const thread = threads.find(({ id }) => id === activeThreadId); 
  const [isOpenThreadInfo, setIsOpenThreadInfo] = useState(false);
  const conversationCreate = useSelector((state) => state.conversationCreate)
  const conversations = useSelector((state) => state.conversations)


  
  const conversation = conversations.map((c) => console.log(c)) <---- this is getting error .map is not a function... same thing if try .find instead.
// this is crashing the app the second the data hits the component.
//If I comment this out, and console.log(conversations) I see the data just fine

  console.log(conversations)
 
  return (
   
    <TabContent className="card-chat-content fs--1 position-relative">
      <TabPane className="card-chat-pane active">
        <ChatContentHeader thread={thread} setIsOpenThreadInfo={setIsOpenThreadInfo} />
        <ChatContentBody thread={thread} isOpenThreadInfo={isOpenThreadInfo} />
      </TabPane>

      <MessageTextArea thread={thread} selContact={selContact} />
    </TabContent>
    
  );
};

export default ChatContent;

这是减速机

const LIST_CONVERSATIONS = 'list_conversations';


export default function (state = [ ], action) {
    switch (action.type) {

        case LIST_CONVERSATIONS:
            return action.payload  
            default:
            return state;
    }
}

这是动作创建者

export const listConversations = () => {
        return async function(dispatch) {
                await 
                axios({
                 url:"http://localhost:5000/conversations",
                 method:"GET", 
                 withCredentials: true
                 }).then( res => dispatch({type: LIST_CONVERSATIONS, payload: res}))
                 }
         }

这是我的后端函数被动作创建者调用

const listConversations = async (req, res) => {
     const { subActServiceSid, subActAuthToken, convoServiceSid} = req.user
     const subClient = require('twilio')(subActServiceSid, subActAuthToken)
     const allConversationSids = []
     const allParticipantSids = []
     const allMessages = []
     await subClient.conversations.services(convoServiceSid)
     .conversations
     .list()
     .then(conversations => conversations.forEach(c => allConversationSids.push(c.sid))); 
     await Promise.all(allConversationSids.map( async (convo) => {
        await subClient.conversations.services(convoServiceSid)
        .conversations(convo)
        .participants
        .list({limit: 20})
        .then(participants => participants.forEach(p => allParticipantSids.push({"conversationSid": p.conversationSid, "participantSid": p.sid, "messagesId": p.conversationSid}) ));
     }))
     res.json(allParticipantSids)
    
    }

标签: node.jsreactjsexpressreduxreact-redux

解决方案


它在 API 结果返回之前工作,这意味着您的初始状态 []很好,并且您的操作设置的状态不是数组。如果它不是一个数组,那么它将没有函数.map.find.

你的问题就在这里:

then( res => dispatch({type: LIST_CONVERSATIONS, payload: res}))

您正在操作有效负载中调度整个 axios 响应对象。该响应对象不是数组。您想要的数组应该在.data响应的属性上。

then( res => dispatch({type: LIST_CONVERSATIONS, payload: res.data}))

推荐阅读