서버 사이드에서 Apollo 상태를 재수화하고 사용자 정의 Redux 상태를 통합하는 방법은 무엇인가요?

서버 사이드에서 Apollo 상태를 재수화하고 사용자 정의 Redux 상태를 통합하는 방법은 무엇인가요? React Apollo를 처음 사용하면 서버 측에서 클라이언트로 상태를 다시 로드하는 문제에 직면할 수 있습니다. 걱정하지 마세요 – 혼자가 아닙니다! 이 문제 해결 안내서에서는 …

title_thumbnail(서버 사이드에서 Apollo 상태를 재수화하고 사용자 정의 Redux 상태를 통합하는 방법은 무엇인가요?)

서버 사이드에서 Apollo 상태를 재수화하고 사용자 정의 Redux 상태를 통합하는 방법은 무엇인가요?

React Apollo를 처음 사용하면 서버 측에서 클라이언트로 상태를 다시 로드하는 문제에 직면할 수 있습니다. 걱정하지 마세요 – 혼자가 아닙니다! 이 문제 해결 안내서에서는 Apollo 상태를 다시로드하고 앱이 사전로드된 상태를 사용하지 않는 문제를 해결하는 단계를 살펴보겠습니다.

문제 이해하기

React Apollo를 사용할 때, 앱이 컴포넌트를 렌더링 한 후에 API 호출 대신 Apollo에서 사전로드된 상태를 렌더링하는지 확인하는 것이 중요합니다. 적절한 구성 없이는 불필요한 API 요청이 발생하여 애플리케이션의 성능에 영향을 줄 수 있습니다.

Redux와의 통합

Redux와 Apollo를 통합할 때 Redux는 Apollo와 함께 사용자 정의 Redux 상태를 렌더링하지 않는다는 일반적인 문제가 발생할 수 있습니다. 이 문제를 해결하기 위해 다음의 단계를 따릅니다:

1. Server.js 코드


const HTML = ({ html, state }) => (
    <html lang="en" prefix="og: http://ogp.me/ns#">
        <head>
            <meta charSet="utf-8" />
            <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
            <meta httpEquiv="Content-Language" content="en" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
        </head>
        <body>
            <div id="app" dangerouslySetInnerHTML={{ __html: html }} />
            <script dangerouslySetInnerHTML={{
                __html: `window.__STATE__=${JSON.stringify(state)};`,
            }} />
            <script src="/static/app.js" />
        </body>
    </html>
);

app.get('/*', (req, res) => {
    const routeContext = {};
    const client = serverClient();

    const components = (
        <StaticRouter location={req.url} context={routeContext}>
            <ApolloProvider store={store} client={client}>
                <WApp />
            </ApolloProvider>
        </StaticRouter>
    );

    getDataFromTree(components).then(() => {
        const html = ReactDOMServer.renderToString(components);
        const initialState = { apollo: client.getInitialState() };

        res.send(`<!DOCTYPE html>\n${ReactDOMServer.renderToStaticMarkup(
            <HTML
                html={html}
                state={initialState}
            />
        )}`);
    });
});

2. ApolloClient.js 코드


import ApolloClient, {
    createNetworkInterface,
    addTypeName,
} from 'apollo-client';

const client = new ApolloClient({
    networkInterface: createNetworkInterface({ uri: testUrl }),
    dataIdFromObject: ({ id }) => id,
    reduxRootKey: state => state.apollo,
    initialState: (typeof window !== 'undefined') ? window.__STATE__ : {},
});

export default client;

3. Store.js 코드


import { createStore, compose, applyMiddleware } from 'redux';
import { syncHistoryWithStore } from 'react-router-redux';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';

import client from '../apolloClient';
import rootReducer from '../Reducers';

const middlewares = [thunk, client.middleware()];
const enhancers = [];

if (!isProduction && isClient) {
    const loggerMiddleware = createLogger();
    middlewares.push(loggerMiddleware);

    if (typeof devToolsExtension === 'function') {
        const devToolsExtension = window.devToolsExtension;
        enhancers.push(devToolsExtension());
    }
}

const composedEnhancers = compose(
    applyMiddleware(...middlewares),
    ...enhancers
);

const store = createStore(
    rootReducer,
    initialState,
    composedEnhancers,
);

export default store;

4. 샘플 컴포넌트 코드


import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

import * as postActions from '../../Redux/Actions/postActions';

class Home extends Component {
    componentWillMount() {
        // console.log('From Will Mount',this.props.posts)
    }

    renderAllPost() {
        const { loading, posts } = this.props;

        if (!loading) {
            return posts.map(data => {
                return <li key={data.id}>{data.title}</li>
            });
        } else {
            return <div>loading</div>
        }
    }

    render() {
        console.log(this.props);
        return (
            <div>
                {this.renderAllPost()}
            </div>
            );
    }
}

const GetallPosts = gql`
    query getAllPosts{
        posts{
            id
            title
            body
        }
    }
`;

const ContainerWithData = graphql(GetallPosts, {
    props: ({ data: { loading, posts } }) => ({
        posts,
        loading,
    }),
})(Home)

export default connect()(ContainerWithData);

결론

이 문제 해결 안내서의 단계를 따라 간다면 서버 측에서 클라이언트로 Apollo 상태를 성공적으로 다시 로드할 수 있습니다. Redux를 Apollo와 올바르게 통합하여 Apollo와 Redux 상태를 올바르게 렌더링하는 것을 기억하세요. 이러한 기술의 조합은 때로는 복잡할 수 있지만 올바른 접근 방식으로 강력하고 성능이 우수한 응용 프로그램을 구축할 수 있습니다.

즐거운 코딩하세요!

참고 자료 :

https://stackoverflow.com/questions/44614666/how-to-rehydrate-my-apollo-state-from-server-side

같은 카테고리의 다른 글 보기 :

reactjs

Leave a Comment