Search code examples
javascriptreactjsmicro-frontend

How do I rerender a different React functional component?


I am trying to solve how to rerender a different functional component.

onComplete: function (data) {
        console.log("everything is complete");
        console.log("this is the applicant id", id);               
        let obj;
        axios
          .post("http://localhost:5000/post_id", {
            applicant_id: id,
          })
          .then((response) => {
            obj = response.data.data.data.json_data.result;
          });
        setTimeout(() => {
          if (obj === "clear") {
            onfidoOut.tearDown(); // <- the Onfido view did not unmount
            renderResult();  // <- BAD APPROACH? `renderResult` renders a HTML node instead of triggers a view rerender.
          }
        }, 3000);
      },

I embarked upon an approach of rendering an HTML node instead of triggering a view rerender because I have never implemented a view rerender to a different component outside of an authentication flow in a class-based component. Also this is a microfrontend application. This is the whole file from where the snippet above is obtained:

const useOnfidoFetch = (URL) => {
  const [token, setToken] = useState();
  const [id, setId] = useState();

  useEffect(() => {
    axios
      .get("http://localhost:5000/post_stuff")
      .then((response) => response.data.data.data.json_data)
      .then((json_data) => {
        console.log("this is the json data", json_data);
        const id = json_data.applicant_id;
        const token = json_data.onfido_sdk_token;
        setId(id);
        setToken(token);
      });
  }, [URL]);

  useEffect(() => {
    if (!token) return;
    console.log("this is working!");
    OnfidoSDK.init({
      token,
      containerId: "root",
      steps: [
        {
          type: "welcome",
          options: {
            title: "Open your new bank account",
          },
        },
        "document",
      ],
      onComplete: function (data) {
        console.log("everything is complete");
        console.log("this is the applicant id", id);
        let obj;
        axios
          .post("http://localhost:5000/post_id", {
            applicant_id: id,
          })
          .then((response) => {
            obj = response.data.data.data.json_data.result;
          });
        setTimeout(() => {
          if (obj === "clear") {
            onfidoOut.tearDown();
            renderResult();
          }
        }, 3000);
      },
    });
  }, [id, token]);

  function renderResult() {
    return <Redirect to="/result" />;
  }
};

export default function() {
  const URL = `${transmitAPI}/anonymous_invoke?aid=onfido_webapp`;
  const result = useOnfidoFetch(URL, {});

     return (
        <div id={onfidoContainerId} />
     )
}

And this is the bootstrap.js file:

import React from 'react';
import ReactDOM from 'react-dom';
import {createMemoryHistory, createBrowserHistory} from 'history';
import App from './App';

// Mount function to start up the app
const mount = (el, { onNavigate, defaultHistory, initialPath}) => {
  const history = defaultHistory || createMemoryHistory({
     initialEntries: [initialPath],
  });

  if (onNavigate) {
    history.listen(onNavigate);
  }

  ReactDOM.render(<App history={history} />, el);

  return {
    onParentNavigate({ pathname: nextPathname }) {
      const {pathname} = history.location;

      if (pathname !== nextPathname) {
        history.push(nextPathname);
      }
    },
  };
};

// If I am in development and isolation
// call mount immediately
if (process.env.NODE_ENV === 'development') {
  const devRoot = document.querySelector('#_marketing-dev-root');

  if (devRoot) {
    mount(devRoot, {defaultHistory: createBrowserHIstory()});
  }
}

// Assuming we are running through container
// and we should export the mount function
export {mount};

Solution

  • It seems obj (from the response) could be used to manage state, for example:

    const [receivedResults, setReceivedResults] = useState(false);
    

    Then when the response is received:

    setReceivedResults(obj === "clear");
    

    and use the flag to allow the component to render itself (not sure of the exact syntax):

    if (receivedResults) {
       return <Redirect to="/result" />;
    } else {
       return null;
    }