relay-tools / react-relay-network-modern-ssr

SSR middleware for react-relay-network-modern
https://github.com/relay-tools/react-relay-network-modern-ssr
MIT License
67 stars 10 forks source link

Does this work with Relay v3.0.0? #12

Open markymc opened 5 years ago

markymc commented 5 years ago

Hi, thank you for creating this library. We're having trouble with getting it to work and are wondering if it will work with Relay v3.0.0? We're able to get the expected data back from the cache via:

const relayData = await relayEnvironment.relaySSRMiddleware.getCache();

however when running the second render:

  const html = ReactDOMServer.renderToString(
    <App
      relayEnvironment={
        new Environment({
          network: Network.create(() => relayData[0][1]),
          store
        })
      }
      req={req}
    />
  );

our QueryRenderer's render function does not receive any props:

const App = props => {
  console.log({ props });
  return (
    <QueryRenderer
      dataFrom={'STORE_THEN_NETWORK'}
      environment={props.relayEnvironment}
      query={graphql`
        query WelcomeScreenQuery {
          works {
            edges {
              node {
                id
                title
                user {
                  first_name
                  last_name
                  profession {
                    name
                  }
                  avatar {
                    thumb_url
                  }
                }
              }
            }
          }
        }
      `}
      variables={{}}
      render={({ error, props }) => {
        console.log('Render QueryRenderer: ', props);

        if (error) {
          console.log('Render QueryRenderer error: ', error);
          return <Text>Search error: {error.toString()}</Text>;
        } else if (props) {
          return <WorksList works={props.works} />;
        }
        return <Text>Loading</Text>;
      }}
    />
  );
};

In the browser, with JS disabled, we just see "Loading". Of course with JS enabled, our page hydrates as needed.

Any help or guidance you could provide would be greatly appreciated!

markymc commented 5 years ago

OK, after debugging ReactRelayQueryRenderer, I discovered that our problem is at

https://github.com/facebook/relay/blob/master/packages/react-relay/ReactRelayQueryRenderer.js#L144

For some reason prevState and nextProps are equal, so the if statement is failing when it should (for us to render the cached Relay data) succeed. If I force that if statement to evaluate to true, the render happens as expected.

But I'm not sure how to actually fix this. If anyone has any thoughts I'd very much appreciate it!

jgcmarins commented 5 years ago

Maybe getDerivedStateFromProps does not work as expect with SSR. Found this at React docs:

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

markymc commented 5 years ago

@jgcmarins Yes that seems to be the case. I'm trying to work out why no-one else is reporting an issue with this though. Surely a lot of people are doing SSR with react-relay.

webican commented 5 years ago

I'm using https://github.com/relay-tools/relay-hooks. There was a ssr related issue that just got resolved https://github.com/relay-tools/relay-hooks/issues/7 and I got relay 4.0.0 to render properly with cached data.