代码之家  ›  专栏  ›  技术社区  ›  FabricioG

componentDidMount中的上下文显示为null

  •  0
  • FabricioG  · 技术社区  · 5 年前

    我目前有一个上下文提供者。

      componentDidMount() {
        if (this.state.memberID === null) {
          try {
            this.checkAuthUser();
          } catch (e) {
            console.error(e);
          }
        }
      }
    
    checkAuthUser = () => {
      new Promise((resolve, reject) => {
    
        this.props.firebase.auth.onAuthStateChanged(authUser => {
          if(authUser) {
            resolve(authUser);
          } else {
              reject(new Error("Not authorized"));
            }
          })
      })
      .then( authDetails => {
        this.props.firebase.getOrgID(authDetails.uid).on('value', snapshot => {
          const setSnapshot = snapshot.val();
          const getOrganizationID = Object.keys(setSnapshot)[0];
          this.setState({ memberID: authDetails.uid, orgID: getOrganizationID })
        })
      })
      .catch(err => console.log(err))
    }
    

    当我尝试在另一个组件中使用它时:

      static contextType = AuthDetailsContext;
    
      componentDidMount() {
        console.log('here is context: ' + this.context.orgID);
        if(this.context.orgID) {
        this.setState({currentOrganization: this.context.orgID, loading: true}, () => {
          this.getMembersInDB('1');
        })
        }
      }
    

    我的console.log为空。意味着上下文尚未注册。知道我做错了什么吗?

    0 回复  |  直到 5 年前
        1
  •  1
  •   James    5 年前

    这里的设计似乎有缺陷,即当您的提供程序被装载时,您发送API请求,然后当您的子代组件被装载时您尝试使用它-这些操作将很快连续发生,比API调用从服务器返回所需的速度快得多。

    在您的供应商中,如果您 必须 在组件安装之前有一个用户,那么您需要延迟呈现子组件,直到您的API响应完成,即。

    const AuthDetailsContext = React.createContext(null);
    
    class AuthDetailsProvider extends PureComponent {
      ...
      componentDidMount() {  
        const { firebase } = this.props; 
        firebase.auth.onAuthStateChanged(authUser => {
          if (!authUser) {
            // Maybe set some other state state to inform the user?
            this.setState({ authError: new Error('Not Authorised') });
            return;
          }
          firebase.getOrgID(authUser.uid)
            .on('value', snapshot => {
              const setSnapshot = snapshot.val();
              const getOrganizationID = Object.keys(setSnapshot)[0];
              this.setState({ 
                authError: null,
                memberID: authUsermemberID.uid, 
                orgID: getOrganizationID 
              });
            });
        })
      }
    
      render() {
        if (this.state.authError) return <b style={{ color: red }}>{this.state.error.message}</b>;
        if (!this.state.memberID) return <b>Authenticating...</b>
    
        return (
          <AuthDetailsContext.Provider value={this.state}>
            {this.props.children}
          </AuthDetailsContext.Provider>
        );
      }
    }