【问题标题】:How to return another component inside condition from stateless component如何从无状态组件返回条件内的另一个组件
【发布时间】:2018-06-30 04:00:48
【问题描述】:

这个无状态组件正在类组件渲染方法中渲染。然后这个无状态组件将根据条件返回 null 或另一个类组件,但它会给我一个错误。

const AdminTools = () => { 
        const userID = auth.currentUser;
        let userRef = firebase.database().ref("users");
        if(userID){
            userRef.child(userID.uid).once('child_added', snap => {
                if(snap.val().role == 'Admin'){
                    return <AdminPanel/>
                        } else {
                      return null     
                        }
            });
        }
    }

错误:

渲染没有返回任何内容。这通常意味着缺少 return 语句。或者,不渲染任何内容,返回 null。

如何根据条件返回某些结果? 我尝试像这样声明变量但同样的错误。

const AdminTools = () => { 
        let res;
        const userID = auth.currentUser;
        let userRef = firebase.database().ref("users");
        if(userID){
            userRef.child(userID.uid).once('child_added', snap => {
                if(snap.val().role == 'Admin'){
                    res =  <AdminPanel/>
                        } else {
                    res = null     
                        }
            });
        }
           return res;
    }

【问题讨论】:

  • 我不明白你在这里想要做什么,AdminTools 是某种递归组件吗?
  • 它是一个无状态组件
  • 您实际上不能拥有运行一些异步效果然后自行重新渲染的无状态组件。因为加载/卸载是状态
  • 完成这项工作的最佳机会是什么?
  • @JuanDelaCruz 你可以创建一个有状态的组件,它在componentDidMount 上加载,并在加载数据后初始呈现 null 和无状态的呈现组件。如 Philippe Leefsma 的回答所述

标签: reactjs firebase-realtime-database jsx react-component


【解决方案1】:

渲染方法不能是异步的,once 方法将回调作为第二个参数。从回调中返回某些内容不会从调用方法返回值,除非您使用 cmets 中提到的 async 或 Promise。

您应该在componentDidMount 中调用userRef.child(userID.uid).once 并根据返回值在组件中使用setState 来触发重新渲染,该重新渲染将返回管理面板或null/false。

如果你想让你的组件保持无状态,那么你就不能在里面运行那个逻辑,一个无状态的组件会将 props 作为输入并总是呈现相同的输出。您可以将异步调用移至父级或在其他地方实现该逻辑,例如在动作处理程序中,这取决于您使用的通量实现。

【讨论】:

    【解决方案2】:

    如果未找到 userId,则渲染不会返回任何内容,如果没有 userId,则需要返回 null

    const AdminTools = () => { 
        const userID = auth.currentUser;
        let userRef = firebase.database().ref("users");
        if(userID){
            userRef.child(userID.uid).once('child_added', snap => {
                if(snap.val().role == 'Admin'){
                    return <AdminTools/>
                } else {
                      return null     
                }
            });
        }
        return null;   // return null here
    }
    

    【讨论】:

    • 为什么会立即返回,只有在没有找到userId的情况下才会返回,认为是if(userID)的else条件
    • 我认为用户 ID 不是立即可用的
    • 在这种情况下,您需要使用 async-await 或 Promise
    猜你喜欢
    • 2019-12-11
    • 2021-02-16
    • 2019-05-30
    • 1970-01-01
    • 2016-02-15
    • 2021-10-18
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    相关资源
    最近更新 更多