为啥我在反应中渲染这个“加载”组件时遇到问题?

Posted

技术标签:

【中文标题】为啥我在反应中渲染这个“加载”组件时遇到问题?【英文标题】:Why do i have a problem rendering this 'Loading' component in react?为什么我在反应中渲染这个“加载”组件时遇到问题? 【发布时间】:2020-04-18 08:02:36 【问题描述】:

我有 2 个组件使用从 json 服务器获取的相同数据。 一个组件使用的数据如下所示:

function Home(props) 
return (
    <div className='container'>
        <div className='row align-items-start'>
            <div className='col-12 col-md m-1'>
                <RenderCard item=props.dish
                    isLoading=props.dishesLoading
                    errMess=props.dishErrMess />
            </div>
            <div className='col-12 col-md m-1'>
                <RenderCard item=props.promotion
                    isLoading=props.promoLoading
                    errMess=props.promoErrMess />
            </div>
            <div className='col-12 col-md m-1'>
                <RenderCard item=props.leader
                    isLoading=props.leaderLoading
                    errMess=props.leaderErrMess />
            </div>
        </div>
    </div>
);

其他组件使用数据如下:

const leaders = props.leaders.map((leader) => 
    return (
        <RenderLeader leader=leader isLoading=props.isLoading
            errMess=props.errMess />
    );
);

RenderLeader 和 RenderCard 组件都具有类似的结构,带有一个 if-else 循环来显示加载动画或错误消息以及实际内容。

function RenderLeader( leader, isLoading, errMess ) 
if (isLoading) 
    return (
        <Loading />
    );

else if (errMess) 
    return (
        <h4>errMess</h4>
    );

else
    return (CONTENT)  

问题是 Home 组件显示加载动画和错误消息,但结构完全相同的其他组件却没有显示。此外,实际上是为第二个组件获取数据,只是它不会显示加载动画和错误消息。这有什么问题?编辑 这就是我调用它们的方式:

<Home
                dish=this.props.dishes.dishes.filter((dish) => dish.featured)[0]
                dishesLoading=this.props.dishes.isLoading
                dishErrMess=this.props.dishes.errMess
                promotion=this.props.promotions.promotions.filter((promo) => promo.featured)[0]
                promoLoading=this.props.promotions.isLoading
                promoErrMess=this.props.promotions.errMess
                leader=this.props.leaders.leaders.filter((leader) => leader.featured)[0]
                leaderLoading=this.props.leaders.isLoading
                leaderErrMess=this.props.leaders.errMess

            />

<Route path='/aboutus' component=() => <About leaders=this.props.leaders.leaders
                            isLoading=this.props.leaders.isLoading
                            errMess=this.props.leaders.errMess /> />

【问题讨论】:

我已经确保所有的道具都正确匹配。 如果你不链接它,我们很难告诉你另一个组件有什么问题:) 如果它们完全相同,那么一定有一个道具差异 - 你没有显示我们如何调用Home(或其他组件) 【参考方案1】:

Home 组件可以正常工作,因为它可以呈现单独的卡片。而对于下面的结构,

const leaders = props.leaders.map((leader) => 
return (
    <RenderLeader leader=leader isLoading=props.isLoading
        errMess=props.errMess />
);
);

如果 props.leaders 为空,它不能迭代,因此 RenderLeader 永远不会被调用。因此,当 props.isLoading 为 true 时,props.leaders 将为空,上面的箭头函数将不返回任何内容。一旦 props.leaders 被填充,上面的函数就会被调用,但是 props.isLoading 已经被设置为 false。 这就是没有显示加载图标或错误消息的原因。

您可以将调用修改为,

<div className="col-12">
       <Media list>
            <RenderLeaderList leaders=props.leaders isLoading= 
                   props.leadersLoading errMess=props.leadersErrMess/>
       </Media>
</div>

并创建一个名为 RenderLeaderList 的新函数;

function RenderLeaderList(leaders, isLoading, errMess)

      if(isLoading)
      
        return(
         <Loading />
        );
      
      else if(errMess)
      
         return(
            <h4>errMess</h4>
         );
      
      else
         if(leaders!=null)
         
            const leaders_map = leaders.map((leader) => 
            return(
                <div key=leader.id className="col-12 mt-5">
                    <RenderLeader leader=leader/>
                </div>
            );
          );
         return (
            <div>
                leaders_map
            </div>
        );
    
   

让它工作。 希望能帮助到你! :D

【讨论】:

以上是关于为啥我在反应中渲染这个“加载”组件时遇到问题?的主要内容,如果未能解决你的问题,请参考以下文章

嵌套反应路由器组件不会在页面重新加载时加载/渲染?

为啥 IE 11 显示空白页渲染反应应用

避免在反应组件中无限重新渲染

为啥在组件加载时不调用 useEffect(()=...,[]) ?

运行反应本机应用程序时出错-检查`App`的渲染方法

在 useQuery 后反应组件不重新渲染