2

我正在尝试利用 React 和 Material Components Web 构建一个模态组件。Modal 的可见性作为 props 从父状态继承:

import React, {Component} from 'react';
import {MDCFormField} from '@material/form-field/';
import {MDCTextfield} from '@material/textfield/';
import './modal.scss';

export default class Modal extends Component {

  componentDidMount() {
  this.email = new MDCTextfield(this.email);
  this.pwd = new MDCTextfield(this.pwd);
}

  componentWillUnmount() {
    this.email.destroy();
    this.pwd.destroy();
  }

  render() {
    if (this.props.isModalOpen){
      return (
        <div id="modal-container">
          <div id="mask"></div>
          <div id="modal">
            <form className="mdc-form-field">

              <div ref={(div) => {this.email = div}} className="mdc-textfield">
                <label type="email" htmlFor="email" className="mdc-textfield__label">Your email</label>
                <input type="text" id="email" className="mdc-textfield__input"/>
                <div className="mdc-textfield__bottom-line"></div>
              </div>

              <div ref={(div) => {this.pwd = div}} className="mdc-textfield">
                <label htmlFor="pw" className="mdc-textfield__label">Password</label>
                <input type="password" id="pw" className="mdc-textfield__input" required minLength={8}/>
                <div className="mdc-textfield__bottom-line"></div>
              </div>

            </form>
          </div>
        </div>
      );
    } else {
      return null
    }
  }
}

一旦应用初始化出现错误“TypeError: Cannot read property 'querySelector' of undefined”</p>

当然,因为模态返回null,所以它确实如此。

所以我尝试将材质组件初始化为

componentDidMount() {
    this.email = this.email && new MDCTextfield(this.email);
    this.pwd = this.pwd && new MDCTextfield(this.pwd);
  } 

在这种情况下,不再抛出错误,但显然组件没有初始化。

我没有想出一个模式来解决这个问题。同样,css 方法也不起作用(想法是从主容器切换 .someClass {display: none} )。

/** 解决了 **/

好的,我想出了一个解决问题的工作模式。问题出在应用程序的架构中,组件的封装不合适。

这是一个名为 Modal 的父组件:

import React, {Component} from 'react';
import EmailField from './email-field';
import PwdField from './password-field';
import './modal.scss';

export default class Modal extends Component {

  render() {
    if (this.props.isModalOpen){
      return (
        <div id="modal-container">
          <div id="mask"></div>
          <div id="modal">
              <form className="mdc-form-field">
                <EmailField />
                <PwdField />
              </form>
          </div>
        </div>
      );
    } else {
      return null
    }
  }
}

比我们有子组件

import React, {Component} from 'react'
import {MDCTextfield} from '@material/textfield/';

export default class EmailField extends Component {

  componentDidMount(){
    this.email = new MDCTextfield(this.email);
  }

  componentWillUnmount(){
    this.email.destroy();
  }

  render(){
    return(
        <div ref={(div) => {this.email = div}} className="mdc-textfield">
          <label type="email" htmlFor="email" className="mdc-textfield__label">Your email</label>
          <input type="text" id="email" className="mdc-textfield__input"/>
          <div className="mdc-textfield__bottom-line"></div>
        </div>
    );
  }
}

我试图从不同范围的 MDCTextfield 元素中初始化和销毁​​。

4

2 回答 2

0

你应该试试这个库的react 版本

于 2017-10-12T08:31:09.590 回答
0

尝试 console.log(this.email)。之后您会看到,您尝试传递的 ref 不是选择器,这在您初始化材料组件时是预期的。 @Fawaz的答案是正确的,但你可以按照你想要的方式实例化它,即使在div.

展示:https ://www.webpackbin.com/bins/-KwEsyJR3O3eW50gX2pq

您是否使用了像我在那里使用的组件?

使用此作为参考: 材料组件文本字段,手动实例化

于 2017-10-12T08:35:03.230 回答