PS: 如果你有疑惑,可以给我留言,咱们一起解决它。
从零搭建一个基于React+Nextjs的SSR网站(一):写在前面
从零搭建一个基于React+Nextjs的SSR网站(二):在Nextjs项目中增加react+redux
从零搭建一个基于React+Nextjs的SSR网站(三):在Next项目中使用markdown
从零搭建一个基于React+Nextjs的SSR网站(四):如何搭建服务器并部署Nextjs项目
正文
基本的Nextjs项目构造可以参考这篇文章,写得很好也非常详细,我就不转载了:
用Next.js快速上手React服务器渲染
看完上面的这篇文章后你会搭建一个自己的本地的静态站点,并且可以运行在localhost:3000。这个时候我们就可以向这个项目上面添加React和Redux了。
与往常的react+redux项目不同的是,以往的react的组件是用Provider容器包裹起来的,可以让容器组件拿到state,比如下面这样
...
import { Provider } from 'react-redux'
import {
BrowserRouter,
Route,
Switch
} from 'react-router-dom'
...
<Provider store={store}>
<BrowserRouter>
<div className="XXX">
<Component1 />
<Switch>
<Route path='/path1' exact component={Component1} />
<Route path='/path2' exact component={Component2} />
</Switch>
</div>
</BrowserRouter>
</Provider>
不过在Nextjs中,不能这么写,Next提供了全局的容器Container。既然用了Next,那就用它提供的方式去解决吧。比如下面这样:
...
import {Container} from 'next/app';
import {Provider} from 'react-redux'
import {withRouter} from 'next/router'
...
@withRouter
class MyApp extends App {
constructor(props) {
...
}
...
render () {
...
return (
<Container>
<Provider store={reduxStore}>
<FrontLayout>
<Component {...pageProps} />
</FrontLayout>
</Provider>
</Container>
);
}
}
export default MyApp
这里的@withRouter是装饰器写法,是一个对类进行处理的函数。修饰器函数的第一个参数,就是所要修饰的目标类。
用代码解释大致是下面这样:
@withRouter
class A {}
// 等于下面这么写
class A {}
A = withRouter(A) || A;
然后你就可以在你的Next项目中使用react+redux了
title-redux.js示例:
const TOGGLE_TITLE = 'TOGGLE_TITLT';
const titleState = {
currentTitle: 'Soy的个人网站'
}
export function TitleReducer(state=titleState, action) {
switch (action.type){
case TOGGLE_TITLE:
return {...state, currentTitle: action.title}
default:
return state;
}
}
export function toggleDispatch(title = titleState.currentTitle){
return {type: TOGGLE_TITLE, title}
}
reducer.js示例:
import { combineReducers } from 'redux'
import { TitleReducer } from './redux/title-redux';
export default combineReducers({TitleReducer})
store.js示例:
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import reducers from './reducer'
import {composeWithDevTools} from 'redux-devtools-extension'
export function initializeStore(initialState = {}) {
return createStore(reducers, initialState, composeWithDevTools(applyMiddleware(thunkMiddleware)))
}