[英]Server side rendering with redux
我有一個使用reactjs和redux構建的簡單應用程序。 由於我剛剛開始學習redux,我在服務器端渲染時遇到了一些問題。
到目前為止我所擁有的是... Client App.js渲染App組件。
render(
<Provider store={store}>
<App />
</Provider>,
document.body
);
一個App組件:
const App = () => (
<div>
<SearchContainer />
<TodoContainer />
</div>
)
如果兩個項都是容器,則SearchContainer從輸入框獲取輸入,觸發一個動作,該動作將使用加載的todo`s(來自遠程休息服務)調度消息。
現在我喜歡在服務器端的頁面加載上加載那些todo,並在頁面顯示后顯示它們。 我該怎么辦? 有沒有辦法在頁面實際顯示之前不使用服務器端渲染和加載項目?
到目前為止,我到目前為止是routes.js文件:
const middleware = [ thunk ]
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger())
}
const store = createStore(reducer,applyMiddleware(...middleware))
app.get('/', function(req, res) {
res.render('home',{
markup: ReactDOMServer.renderToString(
<Provider store={store}>
<App />
</Provider>
)
});
//Some code calling remote service goes here
這通常是加載和應用程序,但我如何將加載的數據推送到TodoContainer? 它應該是某種方式來分派消息,還是應該使用todos數組作為屬性來初始化App組件?
您不需要服務器端渲染。
解決您遇到的問題的最常見方法是從componentDidMount
加載數據。 在返回此數據之前,您需要顯示某些內容,例如微調器或笨蛋或消息或空白頁。 就是那樣子。 您的應用不會是唯一一個帶有加載指示器的應用...
不過,你也可以做的,就是獲取數據的服務器端,你發送的頁面下來之前,和與頁面的送下來<script>
標記和幫助JSON.stringify
。
<script>
window.initialData = {
"myData": [ 1, 2, 3 ]
};
</script>
然后你可以用它來初始化商店。 這使數據立即可用,並消除了對API端點的需求。
const store = createStore(reducer, window.initialData, applyMiddleware(...middleware));
您也可以使用相同的數據在服務器上進行渲染,但無論如何都不需要它。
最后,我想指出你正在渲染document.body
,這是一個壞主意,因為很多瀏覽器擴展和插件為了自己的需要在DOM中添加了div或其他東西。 React不適合那些。 它期望控制它傳遞的元素。 最好只創建一個div
並將其渲染成一個div
。
考慮一下你是否真的需要在todo app中使用SSR。 主要優點是改進了SEO,你的應用程序准備好了一點(它已經渲染)。 如果它不會很重,你可能想跳過它。
有沒有辦法在頁面實際顯示之前不使用服務器端渲染和加載項目?
是的,例如,您可以調度獲取數據的操作並將其推送到componentWillMount
Redux狀態。 在數據不存在之前,您可以渲染某些加載指示器的null
。
好吧,我已經獲得了一些反應,redux,nodejs和其他一些客戶端和服務器端技術的經驗,這是我發現的以及它如何為我工作。
react / redux應用程序中的服務器端呈現包括以下幾個步驟:1。在服務器上加載數據2.將數據從服務器推送到客戶端3.將數據加載到redux存儲
這是一個上傳'redux-polyglot'組件翻譯的小例子。
routes.js [處理快速服務器請求]:
//...all of your imports goes here
import en_phrases from './resources/phrases/en'
app.get('/', async function(req, res) {
const store = createStore(reducers, applyMiddleware(...whatevermiddlewareyouneed))
return res.render('home', {
markup: ReactDOMServer.renderToString(
<Provider store={store}>
<App/>
</Provider>
),
otherPreloadedStateThanPhrases: JSON.stringify(...anythingelse)
phrases: JSON.stringify(en_phrases)
});
}
這里的'home'值是把手模板名稱,它具有:
<script type="application/json" id="phrases">
{{{ phrases }}}
</script>
然后,應用程序的職責是從“短語”腳本標記加載數據,並將其設置為具有多語言提供功能的默認語言。
app.js
const phrases = JSON.parse(document.getElementById('phrases').innerHTML);
const store = createStore(reducers, otherPreloadedStateThanPhrases, applyMiddleware(...middleware));
store.dispatch(setLanguage('en', phrases));
LoginContainer.js [從應用程序中使用的樣本容器]
let LoginContainer = ({p}) => {
<span>{p.tc('login')}</span>
}
exports.LoginContainer = connect((state) => ()(translate(LoginContainer))
其中'login'是從服務器上的短語json加載的值:en.js
export default {
login: "Login"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.