From 59bd6c743384c226a85341c3e24e9fce03026b00 Mon Sep 17 00:00:00 2001 From: youluna Date: Fri, 23 Apr 2021 19:43:18 +0800 Subject: [PATCH] fix(ConfigProvider): side effects of constructor on SSR, close #2920 --- site/zh-cn/contributing.md | 7 ++++--- src/config-provider/index.jsx | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/site/zh-cn/contributing.md b/site/zh-cn/contributing.md index 92db3d263d..47899eb6dd 100644 --- a/site/zh-cn/contributing.md +++ b/site/zh-cn/contributing.md @@ -88,18 +88,19 @@ git checkout -b fix-issue-100 ## 开发注意事项 1. Fusion Next 作为前端组件库支持 SSR 因此需要做到: - - 尽量避免使用 window 等客户端变量 ( server端没有window对象,如果使用需要从window开始逐级判断是否存在 ) - - 客户端端对象的判断用typeof + - 尽量避免在 `constructor` `getDerivedStateFromProps` `componentWillMount (deprecated)` 这些生命周期中,使用 `window` `localStorage` `sessionStorage` `document` `navigator` 等客户端变量; + - 必须使用的话,客户端端对象的判断用typeof ``` if(window && window.autoScroll) => if(typeof window != undefined && window.autoScroll) ) ``` - - 避免往window等全局对象挂载定时器 (可能内存泄漏) + - 避免往window等全局对象挂载定时器 - 避免random()等不确定性输出(输出结果可预期,不依赖于环境等) 2. sass 颜色变量计算的结果,需要以 `$color-calcualte-` 开头,写到组件的 variable.scss 中(不能写到main.scss中),参考`Search`组件,[#1029](https://github.com/alibaba-fusion/next/issues/1029) 3. 所有sass计算需要被calc包裹 +> 《Tips for server-side rendering with React》 https://itnext.io/tips-for-server-side-rendering-with-react-e42b1b7acd57 ## 发布周期 diff --git a/src/config-provider/index.jsx b/src/config-provider/index.jsx index 59ed4c36ff..aeac311569 100644 --- a/src/config-provider/index.jsx +++ b/src/config-provider/index.jsx @@ -177,7 +177,6 @@ class ConfigProvider extends Component { constructor(...args) { super(...args); - childContextCache.add(this, Object.assign({}, childContextCache.get(this, {}), this.getChildContext())); setMomentLocale(this.props.locale); setDateLocale(this.props.locale); @@ -238,6 +237,10 @@ class ConfigProvider extends Component { return null; } + componentDidMount() { + childContextCache.add(this, Object.assign({}, childContextCache.get(this, {}), this.getChildContext())); + } + componentDidUpdate() { childContextCache.add(this, Object.assign({}, childContextCache.get(this, {}), this.getChildContext())); }