You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何将用户登录状态传递给子组件并控制链接显示

Fixing the LoggedIn State Prop Issue Between VideoPlayer and Paywall

Let's walk through the issues in your code and fix them to get the logged-in state properly passed to the Paywall component.

Key Problems Identified

  • No stored loggedIn state: You calculate a loggedIn variable in componentDidMount but don’t save it to the component state, then re-calculate a similar (but error-prone) value directly in the render method. This creates inconsistencies and makes debugging harder.
  • Unhandled request failure edge cases: If the /api/user request fails, this.state.user stays undefined, which doesn’t explicitly reflect the user’s logged-out state.
  • Potential race condition: If fetchData() sets blocking: 'paywall' before the user data request completes, the Paywall might render before the logged-in state is ready.

Step-by-Step Fix

1. Update the Parent Component (VideoPlayer)

First, add loggedIn to your initial state, then calculate and set it properly when fetching user data:

class VideoPlayer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      blocking: undefined,
      user: null,
      loggedIn: false // Default to logged-out state
    };
  }

  async componentDidMount() {
    if (this.md.mobile()) {
      this.setState({ blocking: 'mobile' });
    } else if (this.browser.name === 'ie' || this.browser.name === 'edge') {
      this.setState({ blocking: 'unsupported' });
    } else {
      try {
        const userData = await superagent.get('/api/user');
        if (!userData.error) {
          // Calculate loggedIn based on your API's response rules
          const loggedIn = userData.body.success === undefined; // True if user is logged in
          this.setState({ 
            user: userData.body,
            loggedIn: loggedIn
          }, () => {
            // Ensure user state is updated before fetching additional data
            this.fetchData();
          });
        } else {
          // API returned an error, set loggedIn to false
          this.setState({ loggedIn: false }, () => this.fetchData());
        }
      } catch (err) {
        console.log('Could not fetch user.', err);
        // Request failed, assume user is logged out
        this.setState({ loggedIn: false }, () => this.fetchData());
      }
    }
  }

  render() {
    return (
      <div className='video-player-container'>
        {this.state.blocking === 'paywall' && (
          <Paywall 
            bgImgUrl={this.props.imageUrl('paywall-bg.png')} 
            logoUrl={this.props.imageUrl('logo.png')}
            loggedIn={this.state.loggedIn} // Pass the stored state directly
            {...this.props} 
          />
        )}
      </div>
    );
  }
}

2. Hardening the Child Component (Paywall)

Your Paywall logic is mostly correct, but adding a default prop value ensures we handle edge cases where loggedIn isn’t passed properly:

function Paywall(props) {
  const { iconHrefs, logoUrl, bgImgUrl, config, loggedIn = false } = props; // Add fallback value

  return (
    <div className='blocking-paywall' style={{ backgroundImage: `url(${bgImgUrl})` }}>
      <div className='container'>
        <div className='logo'>
          <img src={logoUrl} />
        </div>
        <h1 className='heading lg'>{content.heading}</h1>
        <div className='message'>
          <div className='subpara'>content</div>
          <div className='subpara'>catchphrase</div>
        </div>
        <div className='login'>
          {/* Show login link only when user is not logged in */}
          {!loggedIn && (
            <p>already a member?<a href='/login'>Login</a></p>
          )}
        </div>
      </div>
    </div>
  );
}

Final Checks

  • Confirm your API response: Make sure logged-in users return success: undefined and logged-out users return success: false — adjust the loggedIn calculation if your API’s response format changes.
  • Verify fetchData(): Ensure it sets blocking: 'paywall' only after the user data is loaded (using the setState callback as shown ensures this).

内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:37:08