React server rendering, how to synchronize client data?

I now pass the data to the component through context of StaticRouter , and then in the componentWillMount of the component, get staticContext through this.props .

but when you refresh the page, you will see that the page is filled with data once, and then a request is made to fill the data again. Later, it is found that the state of the server is not available on the client. All want to ask how to synchronize state ?

.

because the project is relatively simple, redux and mobx are not used.

clipboard.png
clipboard.png

paste the key code:

express :

    const serverSideRender = (req, res) => {
    if(req.url === "/favicon.ico") {
        return ;
    }

    const matchedRoutes = matchRoutes(routes, req.url);
    if(matchedRoutes && matchedRoutes.length) {
        const route = matchedRoutes[matchedRoutes.length -1 ].route;
        const fetcher = route.fetchData ? route.fetchData({...req.params, ...req.query}) : "";
        const promises = [];

        promises.push(fetcher);
        Promise.all(promises).then(data => {
            const context = {...data}; //  context, staticRouter 
            const template = renderToString(
                <StaticRouter location={req.url} context={context}>
                    {renderRoutes(routes)}
                </StaticRouter>
            );

            fs.readFile(path.resolve(BUILD_PATH + "/index.html"), "utf8", (err, data) => {
                if (err) {
                    console.error(err);
                    return res.status(500).send("Oops, better luck next time!");
                }
                return res.send(
                    data.replace("<div id="root"></div>", `<div id="root">${template}</div>`)
                )
            });
        });
    }
};

component:


    componentWillMount() {
        const {staticContext} = this.props;
        this.setState({
            isLoading: !(staticContext && staticContext[0].success),
            listData: staticContext && staticContext[0].success ? staticContext[0].data : []
        });
    }

    componentDidMount() {
        this.fetchData();
    }

since you return the rendering component to the browser after the server pre-fetches the data, you can store the obtained data in window by the way and add a tag to the returned string

<script >
    window.context = {
        state: ${JSON.stringify(data)}
    }
   
</script>

then take it out of the window object as your own state after the client takes over the page

Menu