전통문화대전망 - 전통 미덕 - React 서버 측 렌더링을 효율적으로 사용하는 방법
React 서버 측 렌더링을 효율적으로 사용하는 방법
이번에는 React 서버사이드 렌더링을 효율적으로 사용하는 방법과 React 서버사이드 렌더링 사용 시 주의사항은 무엇인지 알려드리겠습니다. 다음은 실제 사례를 살펴보겠습니다.
React는 컴포넌트(Virtual DOM)를 HTML 문자열로 출력하기 위해 renderToString과 renderToStaticMarkup 두 가지 메소드를 제공합니다. 이는 브라우저 환경에 대한 서버 측 의존성을 제거합니다. 종속성이 있으므로 서버 측 렌더링이 매력적인 것이 됩니다.
브라우저 환경에 대한 의존성을 해결하는 것 외에도 서버 측 렌더링은 두 가지 문제도 해결해야 합니다.
프런트엔드와 백엔드가 코드를 공유할 수 있습니다
터미널 간 라우팅은 균일하게 처리될 수 있습니다.
React 생태계는 다양한 옵션을 제공합니다. 여기서는 설명을 위해 Redux와 React-Router를 선택합니다.
Redux
Redux는 Flux와 유사한 일련의 단방향 데이터 흐름을 제공합니다. 전체 애플리케이션은 하나의 Store만 유지하며 기능 중심의 기능으로 인해 서버에 매우 친숙합니다. 사이드 렌더링 지원.
2분 만에 Redux 작동 방법 알아보기
스토어 정보:
전체 애플리케이션에는 단 하나의 고유한 스토어만 있습니다.
해당 상태 트리 저장 (상태), 리듀서 함수를 호출하여 생성됨(루트 리듀서)
상태 트리의 각 필드는 다른 리듀서 함수에 의해 추가로 생성될 수 있습니다.
저장소에는 디스패치와 같은 여러 메소드가 포함되어 있습니다. 및 getState는 데이터 흐름을 처리하는 데 사용됩니다.
Store의 상태 트리는 이를 변경하기 위해 dispatch(action)에 의해서만 트리거될 수 있습니다.
Redux의 데이터 흐름:
action { type, payload }를 포함하는 객체입니다.
리듀서 함수는 store.dispatch(action)에 의해 트리거됩니다.
리듀서 함수는 두 개의 매개변수(상태, 액션)를 받아들이고 새로운 값을 반환합니다. 상태
리듀서 함수는 action.type을 결정한 다음 해당 action.payload 데이터를 처리하여 상태 트리를 업데이트합니다.
따라서 전체 애플리케이션에서 하나의 Store는 하나의 UI 스냅샷에 해당합니다. 서버 측 렌더링은 서버 측에서 Store를 초기화하고, Store를 애플리케이션의 루트 구성 요소에 전달하고, 루트 구성 요소에서 renderToString을 호출하여 전체 애플리케이션을 초기화 데이터가 포함된 HTML로 출력하는 것으로 단순화됩니다.
react-router
react-router는 페이지에 다양한 구성 요소를 표시하기 위해 선언적 방식으로 다양한 라우팅 결정을 일치시키고 props를 통해 라우팅 정보를 구성 요소에 전달합니다. 경로가 변경되면 소품도 변경되어 구성 요소가 다시 렌더링됩니다.
목록 페이지 /list와 세부정보 페이지 /item/:id라는 두 페이지만 있는 매우 간단한 애플리케이션이 있다고 가정해 보겠습니다.
다음과 같은 경로를 정의할 수 있습니다. ./routes.js
'react'에서 React를 가져옵니다.
'react-router'에서 { Route }를 가져옵니다. ;
import { List, Item } from './comComponents';
// 상태 비저장 구성 요소, 간단한 컨테이너, 반응 라우터는 경로를 기반으로 합니다.
// 규칙과 일치하는 구성 요소는 `props.children`으로 전달됩니다.
const Container = (props) => {
return (
{props.children}
);
};
// 라우팅 규칙:
/ / - `/list`는 `List` 구성요소를 표시합니다.
// - `/item/:id`는 `Item` 구성요소를 표시합니다.
const Routes = (
<경로 경로="/" 구성요소={컨테이너} >
<경로 경로="목록" 구성요소={목록} />
<경로 경로=" item/: id" component={Item} />
);
기본 경로 내보내기; 여기에서 우리는 이것을 매우 전달합니다 서버 측 렌더링 프런트엔드 및 백엔드 구현과 관련된 일부 세부 사항을 설명하는 간단한 애플리케이션입니다.
Reducer
Store는 Reducer에 의해 생성되므로 Reducer는 실제로 Store의 상태 트리 구조를 반영합니다.
./reducers/index.js
'./list'에서 listReducer 가져오기;
'./item'에서 itemReducer 가져오기;
기본 함수 rootReducer(state = {}, action) 내보내기 {< /p >
return {
list: listReducer(state.list, action),
item: itemReducer(state.item, action)
};
}rootReducer의 상태 매개변수는 전체 Store의 상태 트리입니다. 상태 트리 아래의 각 필드에는 자체 감속기가 있을 수도 있으므로 여기서는 listReducer와 itemReducer를 소개합니다. 상태 매개변수는 전체 상태 트리의 해당 목록 및 항목 필드일 뿐입니다.
./reducers/list.js에만 해당됩니다.
constinitialState = [];
기본 함수 내보내기 listReducer(state =initialState, action) { p>
p>
스위치(action.type) {
케이스 'FETCH_LIST_SUCCESS': return [...action.payload];
기본값: 반환 상태 ;
}
}목록은 항목을 포함하는 간단한 배열이며 다음 구조와 유사할 수 있습니다: [{ id: 0, name: 'first item'}, {id: 1, 이름: '두 번째 항목'}], 'FETCH_LIST_SUCCESS'의 action.payload에서 가져옵니다.
그런 다음 획득한 항목 데이터를 처리하는 ./reducers/item.js
constinitialState = {};
내보내기 기본 함수 listReducer(state =initialState , 액션) {
스위치(action.type) {
케이스 'FETCH_ITEM_SUCCESS': return [...action.payload];
기본값: return state;
}
}액션
목록과 항목을 가져오고 리듀서가 Store를 변경하도록 트리거하는 두 가지 해당 액션이 있어야 합니다. 여기서는 정의합니다. fetchList 및 fetchItem 두 가지 작업.
./actions/index.js
'isomorphic-fetch'에서 가져오기 가져오기;
내보내기 함수 fetchList() {
return(디스패치) => {
return fetch('/api/list')
.then(res => res.json())
.then(json => 디스패치({ 유형: 'FETCH_LIST_SUCCESS', 페이로드: json }));
}
}
내보내기 함수 fetchItem(id ) {
return (dispatch) => {
if (!id) return Promise.resolve();
return fetch(`/api/item /${id}`)
.then(res => res.json())
.then(json => dispatch({ type: 'FETCH_ITEM_SUCCESS', 페이로드: json }));
}
}isomorphic-fetch는 프런트엔드와 백엔드 모두에 공통적인 Ajax 구현입니다. 프런트엔드와 백엔드가 코드를 공유하는 것이 중요합니다.
게다가 비동기식 요청이 포함되기 때문에 여기서 작업은 함수인 썽크를 사용합니다. Redux는 이러한 작업을 처리하기 위해 썽크 미들웨어를 사용합니다. fetchList())
Store
Store를 생성하기 위해 별도의 ./store.js 및 구성(예: Apply Middleware)을 사용합니다.
import { createStore } from 'redux';
import rootReducer from './reducers';
// 여기에 미들웨어 적용
// ...
기본 함수를 내보냅니다.configureStore(initialState) {
const store = createStore(rootReducer,initialState);
return store;
}react-redux p>
다음으로 및
./app.js
'react'에서 React 가져오기;
'react-dom'에서 { render } 가져오기;
'react-router'에서 { Router } 가져오기;
'history/lib/createBrowserHistory'에서 createBrowserHistory 가져오기;
'react-redux'에서 { Provider } 가져오기;
'./routes'에서 경로 가져오기;
'./store'에서 구성 저장소 가져오기;
// `INITIAL_STATE`는 서버 측 렌더링에서 옵니다. 자세한 내용은 다음 섹션에 설명되어 있습니다.
constinitialState = window.INITIAL_STATE ;
const store =configureStore(initialState);
const Root = (props) => {
return (
<공급자 저장소={store}>
<라우터 기록={createBrowserHistory()}>
{경로}
);
}
render(
서버 렌더링
다음 서버 측은 비교적 간단합니다. 데이터를 얻으려면 작업을 호출할 수 있습니다. 서버 측에서 경로를 처리하려면 반응 라우터 서버 렌더링을 참조하세요. . 서버 측에서 일치 항목을 사용합니다. 이 메서드는 획득한 요청 URL을 이전에 정의한 경로와 일치시키고 이를 클라이언트와 일치하는 props 개체로 구문 분석하여 구성 요소에 전달합니다.
./server.js
'express'에서 express 가져오기;
'react'에서 React 가져오기;
import { renderToString } 'react-dom/server'에서;
'react-router'에서 { RoutingContext, match } 가져오기;
'react-redux'에서 { Provider } 가져오기; p>
'./routes'에서 경로 가져오기;
'./store'에서configureStore 가져오기;
const app = express();
function renderFullPage(html,initialState) {
return `
${html}
window.INITIAL_STATE = ${JSON.stringify(initialState)};
`; p>
}
app.use((req, res) => {
match({ 경로, 위치: req.url }, (err, 리디렉션 위치, renderProps ) => {
if (err) {
res.status(500).end(`내부 서버 오류 ${err}`);
} else if (redirectLocation) {
res.redirect(redirectLocation.pathname + 리디렉션Location.search);
} else if (renderProps) {
const store =configureStore();
const state = store.getState();
Promise.all([
store.dispatch(fetchList()),
store.dispatch(fetchItem(renderProps.params.id))
])
.then(() => {
const html = renderToString(
p>
);
res.end(renderFullPage(html, store.getState()));
});
} else {
res.status(404).end('찾을 수 없음');
}
});
}); 서버사이드 렌더링 부분은 클라이언트사이드 store.dispatch(action)를 이용하여 Store 데이터를 균일하게 직접 획득할 수 있습니다. 또한 renderFullPage에 의해 생성된 페이지 HTML은 React 컴포넌트의 마운트 부분(
)에 있으며 프런트엔드와 백엔드의 HTML 구조가 일관되어야 한다는 점에 유의하세요. 그런 다음 저장소의 상태 트리를 전역 변수(INITIAL_STATE)에 작성하여 클라이언트가 렌더링을 초기화할 때 서버에서 생성된 HTML 구조를 확인하고 이를 초기화 상태와 동기화할 수 있도록 합니다. 그러면 전체 페이지가 고객.
마지막으로 페이지 내 링크 점프를 처리하는 방법은 무엇입니까?
react-router는 태그를 대체하는 구성 요소를 제공하므로 링크를 클릭할 때마다 서버에 요청하는 대신 다음 작업을 수행할 수 있습니다. 그런 다음 다른 처리를 위해 onClick 이벤트를 바인딩합니다.
예를 들어 /list 페이지에서 각 항목에 대해 는 경로 URL: /item/:id를 바인딩하고 onClick을 바인딩하여 디스패치(fetchItem(id))를 트리거하는 데 사용됩니다. 데이터를 얻으려면 세부정보 페이지 콘텐츠를 표시하세요.
이 기사의 사례를 읽으신 후 방법을 익히셨으리라 생각합니다. 더 흥미로운 정보는 Gxl.com의 다른 관련 기사에도 주목해 주세요!
추천 자료:
vue axios 프로덕션 환경 및 릴리스 환경에서 다양한 인터페이스 주소를 구성하는 단계에 대한 자세한 설명
구현 단계에 대한 자세한 설명 파이를 소수점 100자리까지 JS 계산
p>