【问题标题】:Server side rendering React components that loads state through Ajax服务器端渲染通过 Ajax 加载状态的 React 组件
【发布时间】:2016-10-16 00:38:28
【问题描述】:

我正在努力让我的组件在客户端和服务器端都工作。

这是我的组件的代码:

export default class extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.state = {
            title: props.params.title,
            message: props.params.message
        };
    }

    componentDidMount() {
        $.ajax({
            url: "/get-message",
            success: function (result) {
                this.setState({
                    title: result.title,
                    message: result.message
                });
            }.bind(this),
            cache: false
        });
    }

    render() {
        return (
            <div>
                <h2>{this.state.title}</h2>
                <h3>{this.state.message}</h3>
            </div>
        );
    }
}

它工作正常。当它通过客户端呈现时,它显示 h2h3 为空,然后在 ajax 调用返回时它们被填充。

当它通过服务器渲染时,我已经填充了这些道具,并且发送到客户端的 html 已经完成,不需要任何额外的东西。

问题是当它在服务器上渲染时,我在客户端收到错误消息:

Warning: React attempted to reuse markup in a container but the checksum was invalid. [...]

然后它再次调用 ajax 方法并重新渲染所有内容。

那么我应该如何处理这种情况呢?有没有办法告诉 React 这个组件是在服务器上渲染的,接受它而不调用componentDidMount 方法?

【问题讨论】:

  • 您希望服务器端渲染进行 ajax 调用吗?所以 CLIENT 会有 FINAL 标记?
  • ajax 调用也会调用服务器端可用的方法,因此服务器上没有 ajax 调用。接受的答案做了我需要的。谢谢

标签: reactjs isomorphic-javascript server-side-rendering


【解决方案1】:

解决此问题的常用方法是使用全局状态。您可以在&lt;body&gt; 标记的底部序列化一个JS 对象,其中包含在服务器端计算的状态。

<script>globalState={MyFeature: {title: 'foo'}};</script>

然后使用该状态(或其分支)作为组件的默认值。

例如

if (globalState.MyFeature.title) {
    this.setState({ title: globalState.MyFeature.title });
} else {
    $.ajax(/* ... */);
}

显然,您可以使用 Redux 很好地管理您的全局状态,但您并不真正需要。但是,有许多有用的软件包可以帮助您简化此过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 2021-02-07
    • 2016-04-03
    • 1970-01-01
    • 2017-11-05
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多