gpt4 book ai didi

javascript - 如何在 React/redux 中进行服务器端渲染?

转载 作者:IT老高 更新时间:2023-10-28 23:21:37 27 4
gpt4 key购买 nike

我是 react/redux 的新手,我对 react/redux 中的服务器端渲染有点困惑,是的,我在互联网上看到了一些示例,但是当我尝试使用带有外部服务器的模拟 api 时,服务器端渲染不起作用。

cat.js

import React from 'react';
import {render} from 'react-dom';
import {connect} from 'react-redux';
import * as mockApi from '../Actions/mockActions';
class Cat extends React.Component{
componentWillMount(){
this.props.getMockApi();
}
render(){
return(
<div>
Hello Dude
{this.props.mock.data.map((data,i) => {
return <li key={i}>{data.email}</li>
})}
</div>
)
}
}

const mapStateToProps = (state) => {

return {
mock:state.mock
}
};
const mapDispatchToProps = (dispatch) => {
return {
getMockApi:() => dispatch(mockApi.getMockData())
}
};


export default connect(mapStateToProps,mapDispatchToProps)(Cat);

mockActions.js

import axios from 'axios';
import * as types from './actionTypes';

export function getMockData() {
return dispatch => {
return axios.get('http://jsonplaceholder.typicode.com/users').then(response => {
dispatch(setThisData(response.data))
})
}
}

export function setThisData(data) {

return {
type:types.MOCK_API,
payload:data
}
}

App.js

import React from 'react';
import {render} from 'react-dom';

import Cat from './components/cat'
import {Provider} from 'react-redux';
import configureStore from './Store/configureStore';
import { createStore ,applyMiddleware,compose} from 'redux';
import counterApp from './Reducers'
import thunk from 'redux-thunk';







if(typeof window !== 'undefined'){
// Grab the state from a global variable injected into the server-generated HTML
const preloadedState = window.__PRELOADED_STATE__

// Allow the passed state to be garbage-collected
delete window.__PRELOADED_STATE__
const store = createStore(counterApp, preloadedState, compose(applyMiddleware(thunk)))


render(
<Provider store={store} >
<Cat/>
</Provider>
,
document.getElementById('app')
)



}

devServer.js

import express from 'express';
import path from 'path';
import webpack from 'webpack';
import webpackMiddleware from 'webpack-dev-middleware'
import webpackHotMidleware from 'webpack-hot-middleware';
import bodyParser from 'body-parser';
import React from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux';
import counterApp from '../../src/client/ReduxServer/Reducers';
import App from '../../src/client/ReduxServer/components/cat';
import { renderToString } from 'react-dom/server'


import webpackConfig from '../../webpack.config.dev';


let app = express();
app.use(bodyParser.json());
app.use(express.static('public'))


const compiler = webpack(webpackConfig);

app.use(webpackMiddleware(compiler, {
hot: true,
publicPath: webpackConfig.output.publicPath,
noInfo: true
}));

app.use(webpackHotMidleware(compiler));


// app.get('/*', (req, res) => {
// res.sendFile(path.join(__dirname, '../../index.html'))
// });


//Redux Start
app.use(handleRender);

function handleRender(req,res) {
const store = createStore(counterApp);

const html = renderToString(
<Provider store={store} >
<App/>
</Provider>
)
const preloadedState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(html, preloadedState))
}
function renderFullPage(html, preloadedState) {
console.log(preloadedState)
return `
<!doctype html>
<html>
<head>
<title>Redux Universal Example</title>
</head>
<body>
<div id="app">${html}</div>
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
</script>

<script src="bundle.js"></script>

</body>
</html>
`
}







//Redux Ends








app.listen(3000, () => {
console.log('Listening')
});

现在这只会服务器渲染你好,而不是模拟 Api 调用数据。我知道错过了从服务器端获取数据但关键是我会做什么如果我必须渲染两个组件和那个组件有 5 个 api reuqest,以及如何验证正确的 api 请求

现在我的客户端 Prefecthed 状态将如下所示

 window.__PRELOADED_STATE__ = {"mock":{"data":[]}}

最佳答案

好的,为了清楚起见,您已经创建了处理服务器渲染的代码。但是,它没有加载应该获取的数据对吗?

您已经完成了第一步,太棒了!下一步是将实际的动态数据加载到存储中。让我们看看这里的代码

function handleRender(req,res) {
const store = createStore(counterApp);

const html = renderToString(
<Provider store={store} >
<App/>
</Provider>
)
const preloadedState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(html, preloadedState))
}

发生的事情是您创建了一家商店。该商店用于将 html 呈现为字符串。然后获取存储状态并将其放入 preloadedState。

这是一个很好的接受,renderToString 将调用 this.props.getMockApi(); 正如你所期望的那样。

相反,您必须在调用 renderToString();之前 获取状态;

在这种情况下,您可以执行以下操作。 (请注意,这只是一个示例,您可能希望在生产中使用更通用的东西,特别是如果您使用诸如 react-router 之类的东西。)

import * as mockApi from '../Actions/mockActions';

function handleRender(req, res) {
const store = createStore(counterApp);

store.dispatch(mockApi.getMockData())
// And since you used redux-thunk, it should return a promise
.then(() => {
const html = renderToString(
<Provider store={store}>
<App/>
</Provider>
)
const preloadedState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(html, preloadedState))
});
}

简单吧? ;D,不,只是在开玩笑。这是 react 的一部分,其中还没有真正解决问题的确切方法。

就个人而言,如果我可以选择回到过去,我会告诉自己学习服务器渲染以外的其他东西。我可以使用其他技术,例如代码拆分、延迟加载等。使用服务器渲染,如果 javascript 在用户看到初始页面后很久才到达,他们可能会对其他需要 js 的事情感到沮丧。例如,在我的情况下,一些链接不起作用,一些按钮不起作用,等等。

我并不是说服务器渲染不好。这是一个有趣的技术,只是有其他技术更有益于先学习(哦,服务器渲染基本上会锁定你使用 nodejs 作为后端)。祝你好运:)

关于javascript - 如何在 React/redux 中进行服务器端渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42933875/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com