Luke Vanzweden
Luke Vanzweden

Reputation: 646

ReactJS update UI or call method from different class

I have two classes, App and qrCode. The qrCode class returns a image of the qrcode based on the address provided in that classes state. The app class displays the qrcode component. In the method getSessionID, the app makes a request to the server, then should call updateQrCode to update the qrcode that is being shown.

How can I call the method updateQrCode from App.js? I can't instantiate a new QrCode, because that is not the instance that is being displayed.

App.js:

import React, { Component } from "react";
import "./App.css";

import QrCode from "../qrCode/qrCode";

class App extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <QrCode />
        </header>
      </div>
    );
  }

  getSessionID() {
    fetch("/getSessionID")
      .then((res) => {
        // code here to update the qr code in the instance of QrCode
        // QrCode.updateQrCode("test")
      })
      .then((data) => console.log(data.message));
  }
}

export default App;

QrCode.js:

import "./qrCode.css";
import QRCode from "qrcode";
import React, { Component } from "react";

class QrCode extends Component {
  constructor(props) {
    super(props);
    this.state = {
      qrCode: {
        address: null,
        image: null,
      },
    };
  }

  componentDidMount() {
    generateQrCode(this.state.qrCode.address).then(
      function (image) {
        this.setState({
          qrCode: {
            address: this.state.qrCode.address,
            image: image,
          },
        });
      }.bind(this)
    );
  }

  updateQrCode = () => {
    this.setState({
      qrCode: {
        address: "asdf",
        image: null,
      },
    });
  };

  render() {
    return (
      <div>
        <img src={this.state.qrCode.image} alt="QR Code"></img>
      </div>
    );
  }
}

function generateQrCode(address) {
  return new Promise(function (resolve, reject) {
    if (address) {
      QRCode.toDataURL(address, {
        errorCorrectionLevel: "h",
        color: {
          dark: "#000000",
          light: "#0000",
        },
      })
        .then((dataURI) => {
          resolve(dataURI);
        })
        .catch((err) => {
          console.error(err);
          reject(err);
        });
    } else {
      return address;
    }
  });
}

export default QrCode;

Upvotes: 0

Views: 63

Answers (1)

Rajdeep D
Rajdeep D

Reputation: 3910

App.js is the parent component and QrCode.js is the child component. From parent to child you can pass by props directly.

In App.js, create a state object and update it on receiving fetch response. React re-renders component and its children whenever state object changes.

App.js

import React, { Component } from "react";
import "./App.css";

import QrCode from "../qrCode/qrCode";

class App extends Component {
  constructor(props) {
    super(props);

  this.state = { qrCodeImage: null};
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <QrCode qrCodeImage={this.state.qrCodeImage} />
        </header>
      </div>
    );
  }

  getSessionID() {
    fetch("/getSessionID")
      .then((res) => {
        // code here to update the qr code in the instance of QrCode
        // QrCode.updateQrCode("test")
      })
      .then((data) => this.setState({ qrCodeImage:data }));
  }
}

export default App;

QrCode.js

updateQrCode = () => {
    this.setState({
      qrCode: {
        address: "asdf",
        image: this.props.qrCodeImage,
      },
    });
  };

Upvotes: 1

Related Questions