You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
因为使用的是虚拟 DOM,而虚拟 DOM 是真实 DOM 的一个 JavaScript 对象映射,React 在做页面操作时,实际上不是直接操作 DOM,而是操作虚拟 DOM,也就是操作普通的 JavaScript 对象,这就使得 SSR 成为了可能。在服务器,我可以操作 JavaScript 对象,判断环境是服务器环境,我们把虚拟 DOM 映射成字符串输出;在客户端,我也可以操作 JavaScript 对象,判断环境是客户端环境,我就直接将虚拟 DOM 映射成真实 DOM,完成页面挂载。
importfetchfrom'isomorphic-unfetch'constPost=props=>{if(props&&props.show){return(<><h1>{props.show.name}</h1><p>{props.show.summary.replace(/<[/]?p>/g,'')}</p><imgsrc={props.show.image ? props.show.image.medium : ''}/></>)}}Post.getInitialProps=asyncfunction(context){const{ id }=context.queryconstres=awaitfetch(`http://api.tvmaze.com/shows/${id}`)constshow=awaitres.json()return{ show }}exportdefaultPost
const{ createServer }=require('http')constos=require('os')const{ parse }=require('url')constnext=require('next')constdev=process.env.NODE_ENV!=='production'constapp=next({ dev })consthandle=app.getRequestHandler()constPORT=3100constmyHost=getLocalIP()functiongetLocalIP(){constinterfaces=os.networkInterfaces()for(letdevNameininterfaces){constiface=interfaces[devName]for(vari=0;i<iface.length;i++){constalias=iface[i]if(alias.family==='IPv4'&&alias.address!=='127.0.0.1'&&!alias.internal){returnalias.address}}}}app.prepare().then(()=>{createServer((req,res)=>{constparsedUrl=parse(req.url,true)handle(req,res,parsedUrl)}).listen(PORT,err=>{if(err)throwerrconsole.log(`Server running at http://${myHost}:${PORT}`)})})
Next.js 使用总结
SSR VS CSR
概念
SSR 即服务端渲染(Server Side Rendering),对应的就是 CSR ,客户端渲染(Client Side Rendering)。
区别:
作用:
同构
由于服务端渲染的页面交互能力有限,如果要实现复杂交互,还是要通过引入 js 文件来辅助实现,我们把页面的展示内容和交互写在一起,让代码执行两次,这种方式就叫 同构。
对于一些 js 操作,如事件绑定,dom 操作等,在服务端渲染的 html 文本无法执行,所以这些 js 逻辑必须是在浏览器端才能执行,这里我们将目标页面的代码,在浏览器进行二次渲染:
与
render()
相同,但它用于在 ReactDOMServer 渲染的容器中对 HTML 的内容进行 hydrate 操作。React 会尝试在已有标记上绑定事件监听器。看到这里,会有个疑问:在 Node 环境下,是没有 DOM 这个概念存在的,那 Node 环境下执行,必定会报错,那为何 React 它们就不会报错呢?这一切源于 React 的虚拟 DOM。
因为使用的是虚拟 DOM,而虚拟 DOM 是真实 DOM 的一个 JavaScript 对象映射,React 在做页面操作时,实际上不是直接操作 DOM,而是操作虚拟 DOM,也就是操作普通的 JavaScript 对象,这就使得 SSR 成为了可能。在服务器,我可以操作 JavaScript 对象,判断环境是服务器环境,我们把虚拟 DOM 映射成字符串输出;在客户端,我也可以操作 JavaScript 对象,判断环境是客户端环境,我就直接将虚拟 DOM 映射成真实 DOM,完成页面挂载。
关于 SSR 原理讲得比较好的一篇文章:React 中同构(SSR)原理脉络梳理。
Next.js
功能:
静态文件服务
Next.js 支持将静态文件(例如图片)存放到根目录下的 public 目录中,并对外提供访问。public 目录下存放的静态文件的对外访问路径以 (/) 作为起始路径。如:
然后直接引入:
<img src="/static/img/logo.png" />
,public 文件夹还可用于存放robots.txt
、favicon.ico
等静态文件。自定义
Document
pages 下自定义
_document.js
,这里可以配置一些通用 meta 信息,以及埋点信息等,如:自定义配置文件
在根目录下增加
next.config.js
文件,比如配置了 env:获取数据
注意:getInitialProps 不能使用在子组件中,只能使用在 pages 中
项目打包
next build
打包项目;next start
启动打包后的项目,先运行next build
命令才能运行该命令;配置 Babel
在根目录下增加
.babelrc
文件,由于使用了 Ant Design of React,为了兼容 IE11,需要添加相应的 Polyfill,在内置的next/babel
里可以直接使用targets
配置:绝对路径引用
在根目录下增加
jsconfig.json
文件Window is not defined
有时候我们使用的插件,会被告知 window is not defined,怎么办?可以如下解决:
如果当模块包含仅在浏览器中可用的库时,可利用next/dynamic 设置ssr为false,则仅在浏览器中加载:
使用 react-redux
项目结构
使用www.mindatoz.cn项目中的结构:
rootReducer.js
modules/user.js
部分内容引入
immer
index.js
引入
redux redux-thunk
_app.js
在
pages/_app.js
下引入react-redux
,next-redux-wrapper
:使用 Hooks 获取、更新
使用 Class 获取、更新
如果使用了 Class,需要借助 connect 高阶组件函数:
自定义启动服务
在根目录下增加如
server-local.js
,并在 package.json 配置启动,这样就可以通过访问本机 ip 同步测试跨端浏览器:参考资料
The text was updated successfully, but these errors were encountered: