从this.props.children反应访问Dom节点

Tea*_*ime 6 reactjs

假设我有一张包含登录表格的卡片

 <Card>
     <LoginForm/>
 </Card>
Run Code Online (Sandbox Code Playgroud)

如何从卡片渲染功能中的表单访问节点?

<Form >
  <input type="text" name="email"/>
  <input type="password" name="password"/>
  <input type="submit"/>
 </Form>
Run Code Online (Sandbox Code Playgroud)

因为我想要做的是渲染提交按钮不在props.children上下文中,但渲染它包装在给定的孩子之外!

render () {
return (
  <div className="card">
      <div className="inner">
        {/* render Children */}
        {this.props.children != undefined ?
          <div className="childrenWrapper">
            {this.props.children}
          </div>
          : ""
        }
       </div>
       {/* render submit from login form here, not above  */
  </div>)
Run Code Online (Sandbox Code Playgroud)

示例预期结果

有一些组件实际上做我想要的.例如,来自react-toolbox的Tabs组件.他们以某种方式设法在其他地方呈现Tab(儿童)内的内容

就是这样

   <Tabs index={this.state.inverseIndex} onChange={this.handleInverseTabChange} inverse>
      <Tab label='First'><small>First Content</small></Tab>
      <Tab label='Second'><small>Second Content</small></Tab>
      <Tab label='Third'><small>Third Content</small></Tab>
      <Tab label='Disabled' disabled><small>Disabled Content</small></Tab>
    </Tabs>
Run Code Online (Sandbox Code Playgroud)

这将导致以下html 渲染的HTML示例

正如您可以看到来自选项卡中的子项在其自己的部分中呈现我不想更改表单上的任何内容来解决此问题,我想将表单传递到卡中并让卡片决定表单将如何在卡片渲染功能中呈现.

由于我正在尝试实施Google Material Design Card 组件并将其用作模板,因此需要将更多元素拆分并放置在我希望它们的位置.问题是我实际上可以在表单周围放置相关的HTML以将其作为我想要的卡片,但之后我根本不需要该组件.

nat*_*nai 4

这里有一些不错的答案,但没有一个直接回答您的问题。因此,即使您应该重构代码(如下所述),我仍将为您提供一个可行的解决方案:

class Card extends React.Component {
  constructor() {
    super();
    this.state = {};
  }

  render() {
    console.log(typeof this.props.children)
    return (
      <div>
        {typeof this.props.children === 'object'
          ? React.cloneElement(this.props.children, { ref: (n) => this.form = n })
          : null}
        <button onClick={(e) => console.log(this.form.data)}>submit</button>
      </div>
    );
  }
}

class Form extends React.Component {
  constructor() {
    super();
    this.onChange = this.onChange.bind(this);
    this.state = {};
  }

  onChange(e) {
    this.data = e.target.value;
  }

  render() {
    return (
      <form>
        <input type="text" onChange={this.onChange} />
      </form>
    );
  }
}

ReactDOM.render(
  <Card><Form /></Card>,
  document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)

https://jsbin.com/fohehogozo/edit?js,控制台,输出

通过在实例上设置属性,您可以使用ref. 我查了一下typeof === object这里,因为只有一个孩子。

警告:此代码尚未准备好用于生产。永远不要在生产中运行它。我演示的代码是一个可怕的黑客,你永远不应该在家里尝试这个。