簡體   English   中英

我的地圖函數返回 React 組件時出錯

[英]I am getting an error in my map function returning React component

這是我的代碼,其中我在對象數組上運行映射函數,每個對象有 2 個條件檢查,第一個條件中有一個異步操作,然后是 return 語句。錯誤是這個 - 未捕獲的錯誤:對象作為 React 子對象無效(找到:[object Promise])。 如果您打算渲染一組子項,請改用數組。

<ChannelList
          style={{
            padding: '8px',
          }}
        >
          {Promise.all(channelList.map((channel) => 
            {
              console.log(channel);
              const channelMetaData = JSON.parse(channel?.Metadata);
              //If it is one-to-one chat
              console.log(channelMetaData);  
              if(channelMetaData?.isOneToOne){
                listChannelMemberships(channel.ChannelArn,userId).then(async (res)=>{
                  if(res[0].Member.Name==userData.username){
                    console.log("I am this user",res[0].Member.Name);
                    var otherPerson = res[1].Member.Name;
                  }else if(res[1].Member.Name==userData.username){
                    console.log("I am this user",res[1].Member.Name);
                    var otherPerson = res[0].Member.Name;
                  }
                  console.log(otherPerson);
                  return <ChannelItem
                    key={channel.ChannelArn}
                    name={otherPerson}
                    actions={loadUserActions(userPermission.role, channel)}
                    isSelected={channel.ChannelArn === activeChannel.ChannelArn}
                    onClick={e => {
                      e.stopPropagation();
                      channelIdChangeHandler(channel.ChannelArn);
                    }}
                    unread={unreadChannels.includes(channel.ChannelArn)}
                    unreadBadgeLabel="New"
                    >
                    </ChannelItem>
                  })
             }
             else{
              return <ChannelItem
              key={channel.ChannelArn}
              name={channel.Name}
              actions={loadUserActions(userPermission.role, channel)}
              isSelected={channel.ChannelArn === activeChannel.ChannelArn}
              onClick={e => {
                e.stopPropagation();
                channelIdChangeHandler(channel.ChannelArn);
              }}
              unread={unreadChannels.includes(channel.ChannelArn)}
              unreadBadgeLabel="New"
              >
              </ChannelItem>
             }
            }
            ))}
        </ChannelList>

正如錯誤所說,對象在 React 中不是有效的子對象。 您正在使用Promise.all (一個 Promise 對象)的結果作為該 JSX 表達式的結果:

{Promise.all(/*...*/)}

相反,您需要等待Promise.all的承諾與結果數組一起實現。 你不能在渲染時這樣做,你需要在渲染之外做,然后根據結果設置狀態,而不是渲染那個狀態。

這是一個簡單的例子:

 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <script type="text/babel" data-presets="es2017,react"> const {useState, useEffect} = React; // Stand-in for actual retriever function function getThing(id, signal) { // ^^^^^^−−−− this is so you can pass // it to anything that supports signals to cancel the // work if the component unmounts. return new Promise((resolve, reject) => { setTimeout(() => { console.log(`Done getting thing #${id}`); resolve({id}); }, Math.floor(Math.random() * 800)); }); } const Thing = ({thing}) => <div>{thing.id}</div>; const Example = () => { const [things, setThings] = useState(null); // Load on mount useEffect(() => { const controller = new AbortController(); const {signal} = controller; (async () => { try { const things = await Promise.all([1, 2, 3].map(async (id) => { console.log(`Getting thing #${id}...`); const thing = await getThing(id, {signal}); return <Thing thing={thing} />; })); setThings(things); } catch (error) { // ...handle/report error... console.error(error.message, error.stack); } })(); return () => { controller.abort(); } }, []); // [] = just on mount // Return return <div> {things === null && <em>Loading...</em>} {things} </div>; }; ReactDOM.render(<Example />, document.getElementById("root")); </script> <script src="https://unpkg.com/regenerator-runtime@0.13.2/runtime.js"></script> <script src="https://unpkg.com/@babel/standalone@7.10.3/babel.min.js"></script>


map回調也有問題。 例如, if(channelMetaData?.isOneToOne){中的 true 分支不返回任何內容。 您在then回調中有return ,但在map回調中沒有返回值。 您可能會發現對map回調使用async函數並使用await而不是.then很有用。 這可能看起來像這樣:

// (In an `async` function)
const result = await Promise.all(channelList.map(async (channel) => {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^
    console.log(channel);
    const channelMetaData = JSON.parse(channel?.Metadata);
    //If it is one-to-one chat
    console.log(channelMetaData);
    if (channelMetaData?.isOneToOne) {
        const res = await listChannelMemberships(channel.ChannelArn, userId);
// −−−−−−−−−−−−−−−−−^^^^^
        let otherPerson; // Declare it once (and `var` is deprecated)
        if (res[0].Member.Name == userData.username) {
            console.log("I am this user", res[0].Member.Name);
            otherPerson = res[1].Member.Name;
        } else if (res[1].Member.Name == userData.username) {
            console.log("I am this user", res[1].Member.Name);
            otherPerson = res[0].Member.Name;
        }
        console.log(otherPerson);
        return <ChannelItem
            key={channel.ChannelArn}
            name={otherPerson}
            actions={loadUserActions(userPermission.role, channel)}
            isSelected={channel.ChannelArn === activeChannel.ChannelArn}
            onClick={e => {
                e.stopPropagation();
                channelIdChangeHandler(channel.ChannelArn);
            }}
            unread={unreadChannels.includes(channel.ChannelArn)}
            unreadBadgeLabel="New"
        >
        </ChannelItem>;
    } else {
        return <ChannelItem
            key={channel.ChannelArn}
            name={channel.Name}
            actions={loadUserActions(userPermission.role, channel)}
            isSelected={channel.ChannelArn === activeChannel.ChannelArn}
            onClick={e => {
                e.stopPropagation();
                channelIdChangeHandler(channel.ChannelArn);
            }}
            unread={unreadChannels.includes(channel.ChannelArn)}
            unreadBadgeLabel="New"
        >
        </ChannelItem>;
    }
}));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM