我正在尝试利用 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 元素中初始化和销毁。