32 votes

Ouvrir un composant dans une nouvelle fenêtre lors d'un clic dans react

J'ai un composant qui affiche des données. Je dois ouvrir ce composant dans une nouvelle fenêtre en cliquant sur un bouton/lien d'un composant parent.

export default class Parent extends Component {
    construtor(props) {
        super(props);
    }

    viewData = () => {
        window.open('childcomponent.js','Data','height=250,width=250');
    }

    render() {
        return (
            <div> <a onclick={this.viewData}>View Data</a></div>
        )
    }
}

Je ne sais pas comment invoquer un autre composant et l'afficher dans une nouvelle fenêtre de taille spécifiée.

En fait, j'ai besoin d'envoyer un props à ce composant enfant pour qu'il récupère les données de la base de données et les restitue.

34voto

CD.. Points 23701

Vous pouvez utiliser ReactDOM.createPortal pour afficher un composant dans une nouvelle fenêtre en tant que David Gilbertson explique dans son poste :

class MyWindowPortal extends React.PureComponent {
  constructor(props) {
    super(props);
    // STEP 1: create a container <div>
    this.containerEl = document.createElement('div');
    this.externalWindow = null;
  }

  render() {
    // STEP 2: append props.children to the container <div> that isn't mounted anywhere yet
    return ReactDOM.createPortal(this.props.children, this.containerEl);
  }

  componentDidMount() {
    // STEP 3: open a new browser window and store a reference to it
    this.externalWindow = window.open('', '', 'width=600,height=400,left=200,top=200');

    // STEP 4: append the container <div> (that has props.children appended to it) to the body of the new window
    this.externalWindow.document.body.appendChild(this.containerEl);
  }

  componentWillUnmount() {
    // STEP 5: This will fire when this.state.showWindowPortal in the parent component becomes false
    // So we tidy up by closing the window
    this.externalWindow.close();
  }
}

10voto

Ryan Taylor Points 3091

Cette réponse est basée sur Poste de David Gilbertson . Il a été modifié pour fonctionner avec Edge. Pour que cela fonctionne dans Edge div et style doivent être créées avec la fenêtre dans laquelle elles seront rendues .

class MyWindowPortal extends React.PureComponent {
  constructor(props) {
    super(props);
    this.containerEl = null;
    this.externalWindow = null;
  }

  componentDidMount() {
    // STEP 1: Create a new window, a div, and append it to the window. The div 
    // *MUST** be created by the window it is to be appended to (Edge only)
    this.externalWindow = window.open('', '', 'width=600,height=400,left=200,top=200');
    this.containerEl = this.externalWindow.document.createElement('div');
    this.externalWindow.document.body.appendChild(this.containerEl);
  }

  componentWillUnmount() {
    // STEP 2: This will fire when this.state.showWindowPortal in the parent component
    // becomes false so we tidy up by just closing the window
    this.externalWindow.close();
  }

  render() {
    // STEP 3: The first render occurs before componentDidMount (where we open the
    // new window) so container may be null, in this case render nothing.
    if (!this.containerEl) {
      return null;
    } 

    // STEP 4: Append props.children to the container <div> in the new window
    return ReactDOM.createPortal(this.props.children, this.containerEl);  
  }
}

La source modifiée complète peut être consultée ici https://codepen.io/iamrewt/pen/WYbPWN

5voto

samanime Points 13967

Vous n'ouvrirez pas le composant directement. Vous aurez besoin d'une nouvelle page/vue qui affichera le composant. Lorsque vous ouvrirez la fenêtre, vous la ferez pointer sur l'URL appropriée.

En ce qui concerne la taille, vous la fournissez sous forme de chaîne de caractères dans le troisième paramètre de open, ce qui est en fait correct :

window.open('http://example.com/child-path','Data','height=250,width=250');

Notez toutefois que les navigateurs peuvent, pour diverses raisons, ne pas respecter votre demande de largeur et de hauteur. C'est pourquoi il est probablement judicieux d'appliquer également une feuille de style CSS appropriée pour obtenir un espace de la bonne taille, au cas où il s'ouvrirait plus grand que vous ne le souhaitiez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X