brillout / react-streaming

React Streaming. Full-fledged & Easy.
MIT License
220 stars 14 forks source link

Fetching data with `useAsync` does not update html #8

Closed jaybe78 closed 2 years ago

jaybe78 commented 2 years ago

Hello @brillout ,

I don't know whether it's a bug or something in my implementation but let's see. I've extended a boilerplate that you had done I think which comes up with vps/webpack5.

I added react-streaming + redux into the mix to do some testing.

I have 2 components that fetch data using useAsync(): <Movies /> and <Weather/>.

The problem is that, only the <Weather/> component wrapped with React Lazy works, in the sense that I can see the data being shown on the screen.

It seems the other one <Movies /> does not update the stream.

Here is the piece of code to reproduce, you can find the repo where I made those changes there

Please note that I'm using vps beta version 0.4.0-beta.31 because I had more issues with the latest RC, especially with redux.

Below the lazy component successfully fetches data and is displayed in the UI, rather than the bottom ones which fetches data but fails to update the html tree.

const Lazy = React.lazy(() => import('../../components/Weather'))

function Page() {
    const count = useSelector((state) => state.value)
  return (
    <>
      {/* successfully injected into the html */}
      <React.Suspense fallback={<p>Loading weather...</p>}>
          <Lazy />
      </React.Suspense>
     ...
       {/* this is not getting injected into the html */}
       <React.Suspense fallback={<p>Loading movies...</p>}>
        <MovieList />
      </React.Suspense>
    </>
  )
}
import { useAsync } from "react-streaming";

export default function MovieList() {
  const movies = useAsync(async () => {
    const response = await fetch('https://star-wars.brillout.com/api/films.json')
    return response.json()
  })
  return (
    <ul>
      {movies.results.forEach((movie) => {
          console.log(movie.director)
          return (
              <li>
                  {movie.director}
              </li>
          )

      })}
    </ul>
  )
}
export { render };
async function render(pageContext) {
  const { Page, pageProps } = pageContext;
  const store = getStore(pageContext.PRELOADED_STATE)
  hydrateRoot(
    document.getElementById("page-view"),
      <ReactStreaming>
       <Provider store={store}>
        <PageLayout>
         <Page {...pageProps} />
        </PageLayout></Provider>
    </ReactStreaming>
  );
}
async function render(pageContext) {
  const { Page, pageProps } = pageContext;
  const stream = await renderToStream(
      <Provider store={pageContext.store}>
    <PageLayout>
      <Page {...pageProps} />
    </PageLayout></Provider>,
    {
      disable: false,
      webStream: false,
    }
  );

  return escapeInject`<!DOCTYPE html>
    <html>
      <body>
        <div id="page-view">${stream}</div>
      </body>
    </html>`;
}

Thanks for your help

jaybe78 commented 2 years ago

sorry this is my bad...