kmoskwiak / useSSE

use Server-Side Effect ✨in React SSR app
https://kspr.dev/use-sse/
MIT License
139 stars 10 forks source link

hi, data got [null, null] #14

Closed milobluebell closed 3 years ago

milobluebell commented 3 years ago

hi,

what hasresolveDatadone ?

i have followed your samples, but got [ null, null ]

// server/index.ts

    await resolveData(3000);

    const markup = renderToString(
      <ServerDataContext>
        <App />
      </ServerDataContext>,
    );

    let html = fileContent.replace(/\<!-- injected-data --\>/g, data.toHtml());
    if (data) {
      html.replace('<div id="root" />', `<div id="root">${markup}</div>`);
    }
    res.send(html);
// client/index.ts

  <BroswerDataContext>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </BroswerDataContext>
// App.tsx

  const data = useSSE(() => api.getPopularRepos('chinese').then((res) => res.json()), []);

  console.log(data, 111);

// here i expected to got a array data,but

i got expected data in client side, but got [null, null], 111 in server side

i don't know why, ty

milobluebell commented 3 years ago

@kmoskwiak hi buddy

kmoskwiak commented 3 years ago

Hi @milobluebell sorry fot the late response. For some reason I didn't get notifications.

I am not sure what happen in your case because I don't see entire server file. Try with this setup:

// Sever.jsx
import express from "express";
import React from "react";
import { renderToString } from "react-dom/server";
import App from "./App";
import fileContent from "./index.html";
import path from "path";

import { createServerContext } from "use-sse";

const app = express();
app.use("/static", express.static(path.resolve(__dirname, "./build")));

app.use("/", async (req, res) => {
  if (req.url !== "/") {
    return res.status(404).end();
  }

  const { ServerDataContext, resolveData } = createServerContext();

  renderToString(
    <ServerDataContext>
      <App />
    </ServerDataContext>
  );

  const data = await resolveData();

  const markup = renderToString(
    <ServerDataContext>
      <App />
    </ServerDataContext>
  );

  let html = fileContent.replace(/<!-- injected-data -->/g, data.toHtml());

  html = html.replace(/<div id="root"><\/div>/g, `<div id="root">${markup}</div>`);

  res.send(html);
});

app.listen(3000, "0.0.0.0", () => {
  console.log(`${new Date()} Server listening on port 3000`);
});
// App.jsx
import React from "react";
import { useSSE } from "use-sse";

const getPopularRepos = async () => {
  return { message: "Some async data..." };
};

const App = () => {
  const [data] = useSSE(() => {
    return getPopularRepos();
  }, []);

  return (
    <>
      <pre>{data && data.message}</pre>
    </>
  );
};

export default App;
// Client.jsx
import React from "react";
import { hydrate } from "react-dom";
import App from "./App";
import { createBroswerContext } from "use-sse";

const BroswerDataContext = createBroswerContext();

hydrate(
  <BroswerDataContext>
    <App />
  </BroswerDataContext>,
  document.getElementById("app")
);
// index.html.js
const pageParts = `   
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <!-- injected-data -->
        </head>
        <body>
            <div id="root"></div>
        </body>
        <script src="/static/Client.js"></script>
    </html>
`;

export default pageParts;

If you have any questions pleas don't hesitate. I you want to discuss this problem based on your files please send entire files or create CodeSandbox.

Here is Codesandbox with working example: https://codesandbox.io/s/usesse-forked-brt2l?file=/App.jsx

kmoskwiak commented 3 years ago

@milobluebell I'am closing this, hope my answer helped. Please feel free to reopen if you have any other questions.