如何通过地图功能有条件地使用React和Firebase渲染元素?

时间:2018-03-18 16:29:29

标签: reactjs firebase conditional-rendering

我的主要目标是,如果用户在firebase中没有配置文件,则有条件地呈现“创建配置文件”按钮,或者如果用户具有配置文件,则为“编辑配置文件”按钮。

我没有渲染编辑个人资料按钮的问题。我通过比较auth用户“uid”和配置文件的“uid”来检查用户是否有个人资料。如果它们匹配,则会显示编辑按钮。

我的问题是,当编辑按钮呈现时,创建按钮仍然会出现,但它应该消失,因为我有条件地渲染这两个。

我在这里缺少什么?

  

编辑3/23/2018

我已经找到了问题,但我仍然没有解决方案。问题是map函数循环遍历'Profiles'数组,并且正在查找等于登录用户'uid'的'uid'。

但是如果'uid'与登录用户的uid不匹配,'创建按钮仍将呈现,因为'Profiles'数组中有其他配置文件,其uid不等于登录用户的uid 。“

所以我想我的另一个问题是,

如何检查登录用户是否没有数组和/或Firebase数据库中的数据?

这是我的代码:

我有一个名为'Profiles'的数据库,我从中提取信息。

"Profiles" : {
"-L7p-wZNcvgBBTkvmn7I" : {
  "about" : "I'm a full stack web developer with many skills",
  "email" : "email@gmail.com",
  "frameworkOne" : "react",
  "frameworkThree" : "bootstrap",
  "frameworkTwo" : "javascript",
  "name" : "Dylan Prem",
  "projectInfo" : "You're on it!",
  "projectLink" : "https://hiremoredevs.com",
  "projectName" : "HireMoreDevs",
  "uid" : "ABCDEFG1234567"
}

}

反应成分:

class ProfileButtonToggle extends Component {
constructor(props){
    super(props);
    this.state = {
        authUser:null,
        Profiles:[]

    }
}

componentDidMount(){
  const profilesRef = firebase.database().ref('Profiles');
    profilesRef.once('value', (snapshot) => {
    let Profiles = snapshot.val();
    let newState = [];
    for (let profile in Profiles){
      newState.push({
        id: profile,
        uid:Profiles[profile].uid,
      });
    }
    this.setState({
      Profiles: newState
    });
  });   

  firebase.auth().onAuthStateChanged((authUser) => {
      if (authUser) {
        this.setState({ authUser });
      } 
    }); 
}


render() {
    return (
        <div>
        {this.state.authUser ?
                <div>
                    {this.state.Profiles.map((profile) => {
                        return(
                        <div key={profile.id}>
                            {profile.uid === this.state.authUser.uid ?
                            <Nav>
                                <NavItem>
                                    <Link className='btn yellow-button' to={`/edit/${profile.id}`}>Edit Profile</Link>
                                </NavItem>
                            </Nav>
                            :
                            <Nav>
                                <NavItem>
                                    <Link className='btn yellow-button' to={routes.CREATE_PROFILE}>Create Profile</Link>
                                </NavItem>
                            </Nav>
                        }
                        </div>
                    );
                    })}
                </div>
            :
            null
        }
        </div>

    );
  }
}

export default ProfileButtonToggle;

2 个答案:

答案 0 :(得分:1)

经过几周的拔毛,我终于想出了一个解决方案。事实证明,我甚至不需要创造&#39;按钮。

呈现DOM后,

componentDidUpdate 会触发,这是我所需要的。然后,我会检查一个孩子是否有&#39; 个人资料&#39;有 uid 等于登录用户 uid ,如果不是 push() 当前用户 uid 到&#39; 个人资料&#39;并重新加载页面。它确实有效!

换句话说,如果该用户不存在,它将自动创建一个配置文件。

componentDidUpdate() {
    firebase.database().ref("Profiles").orderByChild("uid").equalTo(this.state.authUser.uid).once("value",snapshot => {
        const userData = snapshot.val();
        if (userData){
          console.log("exists!");
        } else {
            const profilesRef = firebase.database().ref('Profiles');
            const Profiles  = {
                uid: this.state.authUser.uid
            }
            profilesRef.push(Profiles);
            window.location.reload();
        }
    });
}

我将条件渲染更改为:

        <div>
        {this.state.authUser ?
            <Nav>
                {this.state.Profiles.map((profile) => {
                    return(
                    <NavItem key={profile.id}>
                            {profile.uid === this.state.authUser.uid ?
                                <Link id='edit-button' className='btn yellow-button job-text' to={`/edit/${profile.id}`}>Edit Profile</Link>
                                : 
                                null
                            }
                    </NavItem>
                );
                })}
            </Nav>
            :
            null
        }
        </div>

页面重新加载按预期呈现的编辑按钮。

完整组件

class ProfileButtonToggle extends Component {
constructor(props){
    super(props);
    this.state = {
        authUser:null,
        Profiles:[],
    }
}




componentDidMount(){
    const profilesRef = firebase.database().ref('Profiles');
        profilesRef.once('value', (snapshot) => {       
            let Profiles = snapshot.val();
            let newState = [];
            for (let profile in Profiles){
              newState.push({
                id: profile,
                uid:Profiles[profile].uid,
              });

            }
            this.setState({
              Profiles: newState
            });
          });

    firebase.auth().onAuthStateChanged((authUser) => {
      if (authUser) {
        this.setState({ authUser });


        } 
    }); 
}

componentDidUpdate() {
    firebase.database().ref("Profiles").orderByChild("uid").equalTo(this.state.authUser.uid).once("value",snapshot => {
        const userData = snapshot.val();
        if (userData){
          console.log("exists!");
        } else {
            const profilesRef = firebase.database().ref('Profiles');
            const Profiles  = {
                uid: this.state.authUser.uid
            }
            profilesRef.push(Profiles);
            window.location.reload();
        }
    });
}


render() {
    return (
        <div>
        {this.state.authUser ?
            <Nav>
                {this.state.Profiles.map((profile) => {
                    return(
                    <NavItem key={profile.id}>
                            {profile.uid === this.state.authUser.uid ?
                                <Link id='edit-button' className='btn yellow-button job-text' to={`/edit/${profile.id}`}>Edit Profile</Link>
                                : 
                                null
                            }
                    </NavItem>
                );
                })}
            </Nav>
            :
            null
        }
        </div>
      );
    }
 }

 export default ProfileButtonToggle;

答案 1 :(得分:1)

快速提示,您的条件渲染器可以使用&&逻辑运算符,因为它在三元运算符的else部分中不返回任何内容

<div>
        {this.state.authUser &&
            <Nav>
                {this.state.Profiles.map((profile) => {
                    return(
                    <NavItem key={profile.id}>
                            {profile.uid === this.state.authUser.uid ?
                                <Link id='edit-button' className='btn yellow-button job-text' to={`/edit/${profile.id}`}>Edit Profile</Link>
                                : 
                                null
                            }
                    </NavItem>
                );
                })}
            </Nav>
        }
        </div>

因此它将渲染&&之后的项目,如果this.state.authUser不可用则为null