React服务器端呈现AJAX setState()-未定义文档

React server-side rendering AJAX setState() - document is not defined

本文关键字:未定义 文档 setState 服务器端 AJAX React      更新时间:2023-09-26

如果没有AJAX请求的响应,我将无法向用户显示任何内容,即我将所有内容都存储在数据库中。我的组件GenericPage.jsx:

export default class GenericPage extends React.Component {
componentWillMount() {
        if (this.store && this.onStoreUpdated) this.store.addChangeListener(this.onStoreUpdated);
        if (!this.state.page && this.state.pageId) {
            this.fetchData();
        }
    }
onPageStoreUpdated() {
        console.info('onPageStoreUpdated');
        var page = PageStore.getCurrentObject();
        this.setState({page: page, loaded: true}); // the error goes away if I comment this out
    }
    render() {
        ...
    }
}

My Express JS服务器代码:

server.get('*', function (req, res) {
        res.header("Access-Control-Allow-Origin", "*");
        match({routes, location: req.url}, (error, redirectLocation, renderProps) => {
            if (error) {
                res.send(500, error.message)
            } else if (redirectLocation) {
                res.redirect(302, redirectLocation.pathname + redirectLocation.search)
            } else if (renderProps) {
                let htmlStr = React.renderToString(<RoutingContext {...renderProps} />);
                res.header("Access-Control-Allow-Origin", "*");
                res.render('layout', { reactHtml: htmlStr });
            } else {
                console.log('not found')
                res.send(404, 'Not found')
            }
        })
    });

全栈跟踪:

/Users/eric/af/frontend_app/node_modules/react/lib/getActiveElement.js:23
    return document.body;
           ^
ReferenceError: document is not defined
    at getActiveElement (/Users/eric/af/frontend_app/node_modules/react/lib/getActiveElement.js:23:12)
    at ReactReconcileTransaction.ReactInputSelection.getSelectionInformation (/Users/eric/af/frontend_app/node_modules/react/lib/ReactInputSelection.js:40:23)
    at ReactReconcileTransaction.Mixin.initializeAll (/Users/eric/af/frontend_app/node_modules/react/lib/Transaction.js:168:30)
    at ReactReconcileTransaction.Mixin.perform (/Users/eric/af/frontend_app/node_modules/react/lib/Transaction.js:133:12)
    at ReactUpdatesFlushTransaction.Mixin.perform (/Users/eric/af/frontend_app/node_modules/react/lib/Transaction.js:134:20)
    at ReactUpdatesFlushTransaction.assign.perform (/Users/eric/af/frontend_app/node_modules/react/lib/ReactUpdates.js:95:38)
    at Object.flushBatchedUpdates (/Users/eric/af/frontend_app/node_modules/react/lib/ReactUpdates.js:175:19)
    at Object.wrapper [as flushBatchedUpdates] (/Users/eric/af/frontend_app/node_modules/react/lib/ReactPerf.js:70:21)
    at ReactDefaultBatchingStrategyTransaction.Mixin.closeAll (/Users/eric/af/frontend_app/node_modules/react/lib/Transaction.js:207:25)
    at ReactDefaultBatchingStrategyTransaction.Mixin.perform (/Users/eric/af/frontend_app/node_modules/react/lib/Transaction.js:148:16)

我使用的是react 0.13.3和react-router 1.0.0

如果只在浏览器中加载数据,请尝试将ComponentWillMount代码移动到ComponentDidMount

事实证明,在服务器端使用React组件是不可能实现的
因此,我将AJAX调用转移到React组件中的componentDidMount,这样它们就不会影响服务器端
我需要在服务器端获得的数据,在我渲染React组件之前,我在服务器端Node JS代码中获得,在任何React组件之外:

server.get('*', function (req, res) {
        res.header("Access-Control-Allow-Origin", "*");
        match({routes, location: req.url}, (error, redirectLocation, renderProps) => {
            if (renderProps) {
                someAsyncHttpRequest(someUrl)
                    .onSuccess((response) => {
                         page = response.body;
                         renderProps.params.page = page;
                         Dispatcher.dispatch({
                              actionType: AppAction.PAGE_FETCHED,
                              data: page
                         });
                    });
                let htmlStr = React.renderToString(<RoutingContext {...renderProps} />);
                res.render('layout', { reactHtml: htmlStr });
            }
        })
    });