2017-10-05 3 views
0

J'utilise UploadCare dans une modalité qui est en cours de rendu via un portail (à partir de React 16). UploadCare fonctionnait très bien dans le modal jusqu'à ce que je créé un React portail puis l'erreur ci-dessous a eu lieu:UploadCare impossible de trouver le sélecteur de correspondance d'élément DOM après avoir créé React Portal

Error: No DOM elements found matching selector 
▶ 2 stack frames were collapsed. 
UploadCare.componentDidMount 
src/components/UploadCare.js:8 
    5 | class UploadCare extends Component { 
    6 | componentDidMount() { 
    7 |  const { onChange } = this.props; 
> 8 |  const widget = uploadcare.Widget(`#${this.id}`); 

Je crée mon portail comme ceci: https://codepen.io/gaearon/pen/yzMaBd

UploadCare nécessite un sélecteur DOM, dans lequel je m en utilisant un appelé ID. Code ci-dessous:

class UploadCare extends Component { 
    componentDidMount() { 
    const { onChange } = this.props; 
    const widget = uploadcare.Widget(`#${id}`); 

    if (onChange && typeof onChange === "function") { 
     widget.onChange(file => { 
     if (file) { 
      file.done(info => onChange(info.cdnUrl)).fail(() => onChange(null)); 
     } else { 
      onChange(null); 
     } 
     }); 
    } 
    } 

    render() { 
    const { id, name } = this.props; 
    return (
     <input 
     type="hidden" 
     name={name} 
     id={id} 
     data-public-key={process.env.REACT_UPLOADCARE_PUBLIC_KEY} 
     /> 
    ); 
    } 
} 

J'ai corrigé l'erreur en utilisant une référence, mais je ne comprends pas pourquoi l'erreur est survenue. Quelqu'un peut-il m'expliquer ce qu'un portail a fait pour affecter le DOM et mon sélecteur CSS et pourquoi cela nécessite-t-il que j'utilise maintenant un ref pour trouver l'élément DOM? Merci!

Répondre

1

Utiliser ref est le bon moyen. Official documentation of React suggère d'utiliser ref pour l'intégration avec des bibliothèques DOM tierces (comme le widget Uploadcare). Donc, ce bon code:

class UploadCare extends Component { 
    componentDidMount() { 
    const { onChange } = this.props; 
    const widget = uploadcare.Widget(this.uploader); 

    if (onChange && typeof onChange === "function") { 
     widget.onChange(file => { 
     if (file) { 
      file.done(info => onChange(info.cdnUrl)).fail(() => onChange(null)); 
     } else { 
      onChange(null); 
     } 
     }); 
    } 
    } 

    render() { 
    const { id, name } = this.props; 
    return (
     <input 
     type="hidden" 
     ref={input => this.uploader = input} 
     name={name} 
     id={id} 
     data-public-key={process.env.REACT_UPLOADCARE_PUBLIC_KEY} 
     /> 
    ); 
    } 
} 

Qu'en est-il de id? Donc, dans votre code que vous utilisez ${id} en un seul endroit

const widget = uploadcare.Widget(`#${id}`); 

et ${this.id} dans un autre endroit

> 8 |  const widget = uploadcare.Widget(`#${this.id}`); 

Mais, une portée de componentDidMount ces variables ne sont pas définies.

Essayez d'utiliser des accessoires

const { onChange, id } = this.props; 
    const widget = uploadcare.Widget(`#${id}`); 

ou

const { onChange } = this.props; 
    const widget = uploadcare.Widget(`#${this.props.id}`); 

De toute façon, l'utilisation de ref est mieux.

Et merci! J'ai mis à jour https://github.com/uploadcare/uploadcare-widget-react-demo/