简体   繁体   中英

Server side rendering generating different markup than client side rendering

I am doing server side rendering using express and react-router :

This is my code on the server side:

app.use(
    express.static(
        path.join(__dirname,'public')
    )
);

app.set('view engine','ejs');

app.get('*',function(req,res){
   debugger;
   match({
       routes:routes,
       location:req.url,

   },(err,redirect,props) => {
       debugger;
       if(err)
       {
           res.status(500).send(err.message);
       }
       else if(redirect)
       {
           res.redirect(redirect.pathname + redirect.search);
       }
       else if(props)
       {
           const markup = renderToString(<RouterContext {...props}/>);
           debugger;
           res.render('index',{markup});
       }
   });
});

These are my routes :

const routes = (<Route path="/" component={App}>
            <IndexRoute component={Home}/>
            <Route path="/repos" component={Repos}>
                <Route path="/repos/:username/:reponame" component={Repo}/>
            </Route>
            <Route path="/about" component={About}/>
        </Route>);

This is my Repos component:

const Repos = ({children,},context) => {


    const handleSubmit = (event) => {
        event.preventDefault();
        const username=event.target.elements[0].value;
        const repo = event.target.elements[1].value;
        const path = `/repos/${ username }/${ repo }`;
        event.target.elements[0].value='';
        event.target.elements[1].value='';
        context.router.push(path);
        console.log(path);
    }

    return (<div>
        <ul>
            <li><NavLink to="/repos/reactjs/react">React</NavLink></li>
            <li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li>
            <li>
                <form onSubmit={handleSubmit}>
                    <input type="text" placeholder="userName"/>{' '}
                    <input type="text" placeholder="repo"/>{' '}
                    <button type="submit">Go</button>
                </form>
            </li>
        </ul> 
        {children}
    </div>)
};

Repos.contextTypes = {
    router: React.PropTypes.object
};

When I render the repos route, I find that this error occurs when rendering the input element:

bundle.js:1658 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client)  data-reactid="10"><li data-reactid="11"
 (server)  data-reactid="10"><ul data-reactid="11"warning @ bundle.js:1658_mountImageIntoNode @ bundle.js:20285ReactMount__mountImageIntoNode @ bundle.js:7742mountComponentIntoNode @ bundle.js:19941perform @ bundle.js:8231batchedMountComponentIntoNode @ bundle.js:19955perform @ bundle.js:8231batchedUpdates @ bundle.js:16495batchedUpdates @ bundle.js:7389_renderNewRootComponent @ bundle.js:20108ReactMount__renderNewRootComponent @ bundle.js:7742_renderSubtreeIntoContainer @ bundle.js:20185render @ bundle.js:20205React_render @ bundle.js:7742(anonymous function) @ bundle.js:649__webpack_require__ @ bundle.js:556(anonymous function) @ bundle.js:579(anonymous function) @ bundle.js:582

There's not enough information in your post for me to know what exactly is going wrong.

But what I find helps debug this is some simple console.log statements in your client. Wherever your client bootstrap code is that calls ReactDOM.render() , do something like this:

const root = document.getElementById("root");

// add these console.log lines
console.log("before");
console.log(root.innerHTML);

ReactDOM.render(<...whatever.../>, root);

// add these console.log lines
console.log("after");
console.log(root.innerHTML);

Now you can copy those 2 lines of html into a diff tool or text editor and see where they differ.

Usually the difference is because the server renders with different state than the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM