FormidableLabs/react-ssr-prepass

Functional components

codler opened this issue · 5 comments

How do I add fetchData on Functional components? I get undefined on instance visitor function.

This works.

class Home extends React.Component<SampleProps> {
  // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  constructor(props: SampleProps) {
    super(props);
  }

  fetchData = function () {
    console.log("Home -> fetchData -> fetchData", this);
    return fetch("https://google.se");
  };

  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

but this doesnt

const Home = (props) => {
  return <h1>Hello, {props.name}</h1>;
};

Home.fetchData = function () {
  console.log("Home -> fetchData -> fetchData", this);
  return fetch("https://google.se");
};

any clue why?

What does your visitor function look like?

import "fetch-register";
import { createElement } from "react";
import { renderToString } from "react-dom/server";

import Home from "./src/Home";
const ssrPrepass = require("react-ssr-prepass");

const renderApp = async (App) => {
  const element = createElement(App);
  await ssrPrepass(element, (element, instance) => {
    console.log("renderApp -> instance", instance);
    if (instance && instance.fetchData) {
      return instance.fetchData();
    }
  });

  return renderToString(element);
};

renderApp(Home);

@kitten I recreated the issue and you can see the full code here https://codesandbox.io/s/sweet-payne-xiik5?file=/server.tsx

Ah I see; so basically instance there is the literal instance of a class component, the result of what you'd get when calling new YourComponent. Hence it doesn't exist for function components and isn't passed for them.

So when you use function components, you'll have to use the first argument, element, directly. This still gives you access to the component's type (the function itself) and props, but obviously not to any other stateful properties or methods.

Aha okey thank you!