0

In React server components official GitHub example repo at exactly in this line here they are using response.readRoot().

I want to create a similar app for testing something with RSC's and it seems like the response does not contain the .readRoot() function any more (because they have updated that API in the react package on npm and I cannot find anything about it!). but it returns the tree in value property like below:

response

This means that whatever I render in my root server component, will not appear in the browser if I render that variable (JSON.parse(value) || not parsed) inside of my app context provider.

How can I render this?

Basically, if you get some response on the client side (in react server components) you have to render that response in the browser which has the new state from server but since I don't have access to readRoot() any more from response, what would be the alternative for it to use?

halfer
  • 19,824
  • 17
  • 99
  • 186
amdev
  • 6,703
  • 6
  • 42
  • 64
  • I have noticed that little `d` in front of response in above image, and I also noticed that it is not the case for official cloned repo if I try to log the response in their code base, any ideas? – amdev Nov 06 '22 at 11:51

1 Answers1

0

I used a trick o solve this issue, but one thing to keep in mind is that they are still unstable APIs that react uses and it's still recommended not to use React server component in the production level, uses it for learning and test it and get yourself familiar with it, so back to solution:

My experience was I had a lot of problems with caching layer they are using in their depo app. I just removed it. My suggestion is to not use it for now until those functions and APIs become stable. So I Removed it in my useServerResponse(...) function, which in here I renamed it to getServerResponse(...) because of the hook I created later in order to convert the promise into actual renderable response, so what I did was:

export async function getServerResponse(location) {
  const key = JSON.stringify(location);
  // const cache = unstable_getCacheForType(createResponseCache);
  // let response = cache.get(key);

  // if (response) return response;

  let response = await createFromFetch(
    fetch("/react?location=" + encodeURIComponent(key))
  );

  // cache.set(key, response);

  return response;
}

and then creating a hook that would get the promise from the above function, and return an actual renderable result for me:

export function _useServerResponse(appState) {
  const [tree, setTree] = useState(null);

  useEffect(() => {
    getServerResponse(appState).then((res) => {
      setTree(res);
    });
  }, [appState]);

  return { tree };
}

and finally in my AppContextProvider, I used that hook to get the react server component tree and use that rendered tree as child of my global context provider in client-side like below:



import { _useServerResponse } from ".../location/of/your/hook";


export default function AppContextProvider() {
  const [appState, setAppState] = useState({
       ...someAppStateHere
  });
  const { tree } = _useServerResponse(appState);

  return (
    <AppContext.Provider value={{ appState, setAppState }}>
      {tree}
    </AppContext.Provider>
  );
}

I know that this is like a workaround hacky solution, but it worked fine in my case, and seems like until we get stable APIs with proper official documentation about RSCs, it's a working solution for me at least!

amdev
  • 6,703
  • 6
  • 42
  • 64