携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
上篇文章讲解了 服务度渲染中的前端注水
这篇文章讲解写reactStore
初始化 reactStore
使用 react-redux来管理状态
首先安装下redux
yarn add redux react-redux
在src目录下创建store文件夹
在store文件夹下创建index.js来管理store入口
在strore文件夹下创建 actions文件夹,actions文件夹下分别创建 home.js和 person.js来管理这两个的action
在store文件夹下创建reducers文件夹,在reducers文件夹下分别创建home.js和person.js来管理这两个的reducer
首先来写下action
// actions/home.js
export const FETCH_HOME_DATA = 'fetch_home_data';
export const fetchHomeData = async (dispatch) => {
const data = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
articles: [
{
id: 1,
title: 'title1',
content: 'content1'
},
{
id: 2,
title: 'title2',
content: 'content2'
}
]
})
},2000)
})
dispatch({
type: FETCH_HOME_DATA,
payload: data
})
}
export const FETCH_PERSON_DATA = 'fetch_person_data';
export const fetchPersonData = async (dispatch) => {
const data = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
userInfo: {
username: 'curry',
job: '前端工程师'
}
})
},2000)
})
dispatch({
type: FETCH_PERSON_DATA,
payload: data
})
}
让开始写reducers
// reducers/home.js
import { FETCH_HOME_DATA } from '../actions/home';
const initState = {
articles: []
}
export default (state = initState ,action) => {
switch(action?.type){
case FETCH_HOME_DATA:
return action.payload;
default:
return state;
}
}
// reducers/person.js
import { FETCH_PERSON_DATA } from '../actions/person';
const initState = {
info: {}
}
export default (state = initState ,action) => {
switch(action?.type){
case FETCH_PERSON_DATA:
return action.payload;
default:
return state;
}
}
最后将这两个reducer合并起来
在 reducers/index.js中将两个合并
import { combineReducers } from 'redux'
import homeReducer from './home'
import personReducer from './person'
export default combineReducers({
home: homeReducer,
person: personReducer
})
最后在stroe中引入redux
import { createStore } from 'redux'
import reducer from './reducers'
const store = createStore(reducer)
export default store;
开始使用store
在client.js中使用store
在使用store的时候,需要使用到react-redux提供的Provider,相当于context中的provider,
将Provider包裹住,将store传入Provider,这样的话,才能在组件中接受到store
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux'
import Routes from './routes';
import store from './store'
ReactDOM.hydrate(
<Provider store={store}>
<BrowserRouter>
<Routes />
</BrowserRouter>
</Provider>,
document.querySelector('#root')
);
同时也需要在server.js中引入Provider,并将store传入Provider
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom/server'
import { Provider } from 'react-redux'
import Routes from './routes'
import store from './store'
const express = require('express');
const app = express();
const port = process.env.port || 3000;
app.use(express.static('dist/public'))
app.get('*', (req, res) => {
const content = ReactDOMServer.renderToString(
<Provider store={store}>
<StaticRouter location={req.url}>
<Routes />
</StaticRouter>
</Provider>
)
const html = `
<html>
<head></head>
<body>
<div id="root">${content}</div>
<script src="bundle_client.js"></script>
</body>
</html>
`
res.writeHead(200,{
'content-type': 'text/html;charset=utf8'
})
res.end(html)
})
app.listen(port, () => {
console.log('http://localhost:3000')
})