【问题标题】:In ReactJS, how do I render one component within another?在 ReactJS 中,如何在另一个组件中渲染一个组件?
【发布时间】:2020-09-04 04:43:19
【问题描述】:

我正在编写一个 ReactJS 应用程序,并希望显示一个登录页面,该页面显示登录表单或注册表单,具体取决于所访问的链接。

到目前为止,我的 App 组件如下所示:

const App = () => (
  <Router>
    <div>
      <Route path={ROUTES.LANDING}  render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
      <Route path={ROUTES.SIGNIN}   render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
      <Route path={ROUTES.REGISTER} render={(props) => <LandingPage {...props} subPage={RegisterPage} />}/>
      <Route render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
    </div>
  </Router>
);

现在,我不确定如何让实际的子页面显示在登录页面中。

在我的登录页面组件中,我有这个:

class LandingPage extends Component {
  constructor(props) {
    super(props);

    this.state = {props}

  }

  render() {

    return (
      <div className="wrapper">
        <div>{this.state.subPage}</div>
      </div>
    );
  }
}

export default LandingPage;

但是当我转到“登陆页面/登录”时它没有显示任何内容。我可以在控制台中看到 this.state.subPage 包含正确的组件,当我更改 Route 以直接显示 SignInPage 时,效果很好,因此 SignInPage 本身肯定可以正常工作。

我的 SignInPage 组件包含:

const SignInPage = () => (
  <div>
    <p>Sign In</p>
    <SignInForm />
  </div>
);

class SignInFormBase extends Component {
  constructor(props) {
    super(props);

  }

  onSubmit = event => {
    // This will handle form submission
  };

  render() {
    return (
      <form onSubmit={this.onSubmit}>
        <input name="email" placeholder="Email Address" />
        <input name="password" type="password" placeholder="Password" />
        <button type="submit">Sign In</button>
      </form>
    );
  }
}
const SignInForm = compose(
  withRouter,
  withFirebase,
)(SignInFormBase);

export default SignInPage;

export { SignInForm };

我猜可能问题是 SignInForm 是一个组件,但 SignInPage 不是?但是我是 React 新手,所以我不知道如何重新配置​​它们!

接下来我可以尝试什么?

【问题讨论】:

  • 你也可以在你的 JSX 中渲染 &lt;LandingPage ...&gt;&lt;SignInPage /&gt;&lt;/LandingPage&gt; 然后 {this.props.children}
  • 谢谢。很高兴知道这一点。

标签: javascript reactjs


【解决方案1】:

您可以将它们嵌套在LandingPage 组件中,而不是将组件作为props 显式传递给LandingPage 组件

<LandingPage {...props}>
   <SignInPage />
</LandingPage>

SignIn 组件将作为道具传递给LandingPage 组件,并且可以使用props.children 访问

return (
  <div className="wrapper">
    {this.props.children}
  </div>
);

这种方法的一个优点是您可以在LandingPage 组件中嵌套尽可能多的组件,并且它们都将使用this.props.children 呈现在LandingPage 组件中

更改后您的路线将如下所示

<Route path={ROUTES.LANDING} render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage> }/>
<Route path={ROUTES.SIGNIN} render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage>}/>
<Route path={ROUTES.REGISTER} render={(props) => <LandingPage {...props}> <RegisterPage/> </LandingPage>}/>
<Route render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage>}/>

【讨论】:

  • 谢谢。这很有帮助。渲染时有没有办法区分孩子?例如
    {this.props.children.child1}> 或类似的东西?
  • @Sharon this.props.children 将是一个数组。您可以使用数组索引访问和呈现特定的子元素。第一个子元素将位于this.props.children[0] 等等...
【解决方案2】:

在应用组件中:

<Route render={(props) => <LandingPage {...props}><SignInPage /></LandingPage>}/>

在登陆页面组件中:

<div className="wrapper">
 <div>{this.props.children}</div>
</div>

【讨论】:

    【解决方案3】:

    由于您将subPage 作为道具传递给LandingPage,因此您可以从道具中获取该组件并如下所示进行渲染

    class LandingPage extends Component {
      constructor(props) {
        super(props);
    
      }
    
      render() {
        const SubPage = this.props.subPage;
        return (
          <div className="wrapper">
            <div><SubPage /></div>
          </div>
        );
      }
    }
    
    export default LandingPage;
    

    注意:您不需要将道具复制到状态中

    【讨论】:

    • 谢谢!这很有帮助。我已经尝试过了,它有效,非常感谢!
    • (我接受了这个作为正确答案,因为它是我使用的那个,但其他解决方案似乎也可以)
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签