Javascript 在react钩子组件调用useState()时,如何实现条件呈现?

Javascript 在react钩子组件调用useState()时,如何实现条件呈现?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,最近,我试图用React钩子替换项目中的类组件实现,但在实现子组件的条件呈现时遇到了一些问题 我有一个父组件包含页眉、页脚和一个条件呈现子组件,它呈现不同的子组件取决于父组件的状态,其状态由另一个useEffect控制,如下面所述的代码 但是,我的一个子组件包含一个简单的计数器,它由useState()实现,如官方教程中的示例。正如hooks规则所述,我们只能在顶层调用hook,当呈现这些子对象时,我的应用程序崩溃 我想解决方案之一是将子组件的useState()放在父组件中,或者使用类似Red

最近,我试图用React钩子替换项目中的类组件实现,但在实现子组件的条件呈现时遇到了一些问题

我有一个父组件包含页眉、页脚和一个条件呈现子组件,它呈现不同的子组件取决于父组件的状态,其状态由另一个useEffect控制,如下面所述的代码

但是,我的一个子组件包含一个简单的计数器,它由useState()实现,如官方教程中的示例。正如hooks规则所述,我们只能在顶层调用hook,当呈现这些子对象时,我的应用程序崩溃

我想解决方案之一是将子组件的useState()放在父组件中,或者使用类似Redux的实现?但这有点尴尬,因为计数器只是一个简单的逻辑,不需要从组件中取出

所以我正在寻找另一种方法来解决这个问题。当然,如果一开始我的想法是错误的,请告诉我

我的父组件:

conststorepage=(道具)=>{
const{children}=props;
const[detectedTagIds,setDetectedTagIds]=useState([]);
const[detectedProducts,setDetectedProducts]=useState([]);
const fetchProductByTagIds=(tagIds)=>productController.getProducts({tagId:tagIds})
.then(res=>res.json())
.then(json=>setDetectedProducts(json.result))
//监视检测到的标签
useffect(()=>{
ws.addEventListener('消息',(事件)=>{
const json=json.parse(event.data)
const{tagId}=json;
如果(!\包括(检测到的标记ID、标记ID)){
setDetectedTagID(u.concat(detectedTagID,tagId));
}
});
}, []);
//更改检测到的标记时提取
useDeepCompareEffect(()=>{
FetchProductByTagId(检测到的TagId)
},[DetectedTagID]);
返回(
{头({detectedProducts})}
{
detectedTagIds.length==0?
登录页():
(detectedProducts.length==1?ProductInfoPage({detectedProduct:detectedProducts[0]}):null)
}
{页脚({detectedProducts})}
);
};
导出默认存储页面;
这是我收到的错误消息,我认为这是由检测到的产品的更改触发的:

   Previous render            Next render
   ------------------------------------------------------
1. useState                   useState
2. useState                   useState
3. useEffect                  useEffect
4. useRef                     useRef
5. useEffect                  useEffect
6. useState                   useState
7. useState                   useState
8. useState                   useState
9. useRef                     useState
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

即使子组件使用钩子,也可以有条件地呈现子组件,但是您需要使用正常的react方式来实现这一点:要么编写jsx标记,要么手动调用react.createElement(jsx编译为react.createElement)。直接调用子组件作为函数将导致出现问题

return (
  <div className="StorePage">
    <Header detectedProducts={detectedProducts} />
    <div className="StorePage-content">
      {detectedTagIds.length === 0 ? (
        <LandingPage/>
      ) : detectedProducts.length == 1 ? (
        <ProductInfoPage detectedProducts={detectedProducts[0]} />
      ) : (
        null
      )}
    </div>
    <Footer detectedProducts={detectedProducts}/>
  </div>
);
返回(
{detectedTagIds.length==0(
):detectedProducts.length==1(
) : (
无效的
)}
);

哦,看来我犯了一个愚蠢的错误。我不知道为什么,但是当我以前使用jsx标记时会出现错误,所以我在代码中将所有子组件作为函数调用。但是现在当我把它们改回jsx标签时,它工作得非常好,谢谢!“直接调用子组件作为函数将导致您看到的问题。”这是我在阅读该评论之前不理解的一点。谢谢你用这个解决了我的问题!谢谢你,尼古拉斯!