Skip to content

Commit

Permalink
docs: 完善faq.md
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangyuang committed Aug 2, 2019
1 parent 78d0b63 commit 716a22a
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion docs/guide/faq.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# FAQ

## 如何解决服务端访问不可访问的对象的问题

SSR是近几年才火热的话题,如果是新的项目且开发人员对SSR有较深的认知,那么在设计应用的过程中就会有意识的去避免在服务端访问客户端对象的情况。但在老项目或者老的第三方库/框架,或者是开发人员对SSR理解不深刻的情况下,会出现很多类似 `window is not defined` 的错误。
先说前言,个人是不推荐用 `jsdom` 来在服务端模拟客户端环境,这样最多只能模拟最外层的对象例如 `window document` 但如果要访问更深层次的对象例如 `document.getElementById` 则还是会报错。且这种方式新增了一堆很dirty的代码且不利于debug容易造成未知的问题。
自己的代码我们可以控制,那么如果有第三方模块犯了这种问题应该如何解决呢。在有能力给第三方模块提PR的时候还是建议以PR的形式进行修复。例如 `axios` 就会根据你当前的环境来决定到底是用xhr对象还是用http模块来发起请求。如果没办法改动第三方模块,我们可以在代码中延迟加载这些模块,让它在客户端执行的时候被调用。

1. 使用本应用提供的 `__isBrowser__` 常量来判断,例如引入jquery可以使用以下引入方式

```js
import $ from 'jquery' // error
const $ = __isBrowser__ ? require('jquery') : {} // true
```

2.`didMount` 生命周期加载模块

```js
class Page {
this.state = {
$: {}
}
componentDidMount () {
this.setState({
$: require('jquery')
})
}
}
```

3. 如果某个组件调用的库一定要使用浏览器对象才能得到结果,那么只能将该组件放到客户端进行render了,参考[OnlyCsr](./faq.md#如何让某一个组件只在客户端进行渲染)

<span style="color: red">注: 不要想着在服务端去访问客户端对象,这意味着你 or 开发第三方模块的人对React SSR的理解不够, 虽然这一开始会导致一定的错误,但对于你去理解SSR的执行机制以及分清楚Server/Client两端的区别帮助很大</span>

## 开发过程中报content not match的错误如何解决

这种问题原因是你在服务端与客户端渲染了不同的DOM结果。这里我们分两种情况
Expand Down Expand Up @@ -40,7 +72,7 @@ class Page {

使用ykfe-utils提供的高阶组件OnlyCsr

```
```js
import { OnlyCsr } from 'ykfe-utils'

export default OnlyCsr(Page)
Expand Down

0 comments on commit 716a22a

Please sign in to comment.