3

コンポーネントをクライアント側とサーバー側の両方で動作させるのに苦労しています。

これは私のコンポーネントのコードです:

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か?

4

1 に答える 1

3

これを処理する一般的な方法は、グローバル状態を使用することです。<body>サーバー側で計算された状態を含む、タグの下部にある JS オブジェクトをシリアル化できます。

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

次に、その状態 (またはそのブランチ) をコンポーネントのデフォルトとして使用します。

例えば

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

Redux を使用してグローバルな状態を適切に管理できることは明らかですが、実際にそうする必要はありません。ただし、このプロセスを合理化するのに役立つ便利なパッケージが多数あります。

于 2016-06-15T10:56:54.770 に答える