2017-10-12 2 views
0

J'essaie de construire un composant Modal en tirant parti de React et de Material Components Web. La visibilité de Modal est héritée de l'état parent comme accessoires:Composants de matériaux Web et React: Impossible de lire la propriété 'querySelector' de undefined;

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 
    } 
    } 
} 

Dès que l'application initialise une erreur apparaît « TypeError: Impossible de lire la propriété « querySelector » undefined »

Bien sûr, il fait depuis le depuis que le Modal est de retour nul.

donc j'ai essayé de composants des matériaux comme initialiser

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

Dans ce cas, l'erreur n'est pas Thr posséder plus, mais évidemment les composants ne sont pas initialisés.

Je n'ai pas trouvé de modèle pour résoudre ce problème. De plus, une approche css n'a pas fonctionné (l'idée était de basculer .someClass {display: none} du conteneur principal).

/** ** SOLVED/

Ok je suis venu avec un modèle de travail pour résoudre le problème. Le problème résidait dans l'architecture de l'application et l'encapsulation des composants n'était pas appropriée.

Ceci est un composant parent appelé 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 
    } 
    } 
} 

Que nous avons des composants enfants comme

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> 
    ); 
    } 
} 

je tentais de init et détruis d'une portée différente des éléments MDCTextfield.

+0

Pouvez-vous partager quelle bibliothèque matériel que vous utilisez? – Fawaz

+0

Un simple "fil add material-components-web" – TheBluerock

+0

Cela vous aidera https://github.com/material-components/material-components-web – Fawaz

Répondre

0

Vous devriez essayer le react version de cette librairie.

+0

Merci Fawaz mais j'ai eu cette erreur "Constructeur de classe MDCTextfield ne peut pas être appelé sans 'nouveau'." Si je modifie dur état parent (isModalOpen = true) tout fonctionne comme prévu. – TheBluerock

+0

@TheBluerock Je pense que vous devriez essayer quelque chose de plus testé pour fonctionner correctement avec React. Peut-être que ma réponse mise à jour vous aidera mieux! – Fawaz

0

Essayez de console.log (this.email). Ensuite, vous verrez, que ref que vous essayez de passer n'est pas un sélecteur, cela est prévu lorsque vous initialisez les composants matériels. @Fawaz La réponse est correcte, mais vous pouvez l'instancier comme vous le souhaitez, même sur div.

Showcase: https://www.webpackbin.com/bins/-KwEsyJR3O3eW50gX2pq

Avez-vous en utilisant des composants comme je l'utilise là-bas?

Utilisez cette référence pour: Material Components Textfield, Manual Instantiation

+0

console.log (this.email) sort l'objet MDCTextfield avec toutes les propriétés décrites dans sa fondation. – TheBluerock

+0

Ensuite, vous pouvez utiliser cet objet, ou utiliser la version de réaction, comme indiqué _ @ Fawaz_ –