服务器端渲染通过 Ajax 加载状态的 React 组件
Server side rendering React components that loads state through Ajax
我正在努力让我的组件在客户端和服务器端工作。
这是我的组件的代码:
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>
);
}
}
它工作正常。当它通过客户端呈现时,它显示 h2
和 h3
为空,然后当 ajax 调用 returns.
时它们被填充
当它通过服务器呈现时,我已经填充了这些道具并且 html 发送到客户端已经完成并且不需要任何额外的东西。
问题是当它在服务器上呈现时,我在客户端收到错误消息:
Warning: React attempted to reuse markup in a container but the checksum was invalid. [...]
然后它再次调用 ajax 方法并重新呈现所有内容。
那么我该如何处理呢?有没有办法告诉 React 这个组件是在服务器上呈现的接受它而不是调用 componentDidMount
方法?
一种常见的处理方法是使用全局状态。您可以在 <body>
标记的底部序列化一个 JS 对象,其中包含在服务器端计算的状态。
<script>globalState={MyFeature: {title: 'foo'}};</script>
然后将该状态(或其分支)用作组件的默认状态。
例如
if (globalState.MyFeature.title) {
this.setState({ title: globalState.MyFeature.title });
} else {
$.ajax(/* ... */);
}
显然您可以使用 Redux 很好地管理您的全局状态,但您并不真的需要。但是,有许多有用的软件包可以帮助您简化此过程。
- react router redux
- redux-async-connect
- serialize-javascript - 你可以在没有 redux 的情况下使用这个
我正在努力让我的组件在客户端和服务器端工作。
这是我的组件的代码:
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>
);
}
}
它工作正常。当它通过客户端呈现时,它显示 h2
和 h3
为空,然后当 ajax 调用 returns.
当它通过服务器呈现时,我已经填充了这些道具并且 html 发送到客户端已经完成并且不需要任何额外的东西。
问题是当它在服务器上呈现时,我在客户端收到错误消息:
Warning: React attempted to reuse markup in a container but the checksum was invalid. [...]
然后它再次调用 ajax 方法并重新呈现所有内容。
那么我该如何处理呢?有没有办法告诉 React 这个组件是在服务器上呈现的接受它而不是调用 componentDidMount
方法?
一种常见的处理方法是使用全局状态。您可以在 <body>
标记的底部序列化一个 JS 对象,其中包含在服务器端计算的状态。
<script>globalState={MyFeature: {title: 'foo'}};</script>
然后将该状态(或其分支)用作组件的默认状态。
例如
if (globalState.MyFeature.title) {
this.setState({ title: globalState.MyFeature.title });
} else {
$.ajax(/* ... */);
}
显然您可以使用 Redux 很好地管理您的全局状态,但您并不真的需要。但是,有许多有用的软件包可以帮助您简化此过程。
- react router redux
- redux-async-connect
- serialize-javascript - 你可以在没有 redux 的情况下使用这个