diff --git a/.babelrc b/.babelrc old mode 100644 new mode 100755 diff --git a/.circleci/config.yml b/.circleci/config.yml old mode 100644 new mode 100755 diff --git a/.eslintignore b/.eslintignore old mode 100644 new mode 100755 diff --git a/.eslintrc b/.eslintrc old mode 100644 new mode 100755 diff --git a/.flowconfig b/.flowconfig old mode 100644 new mode 100755 diff --git a/.gitattributes b/.gitattributes old mode 100644 new mode 100755 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.nvmrc b/.nvmrc old mode 100644 new mode 100755 diff --git a/.prettierrc b/.prettierrc old mode 100644 new mode 100755 diff --git a/README.md b/README.md index bc31db6083..17b0e6dd88 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -# React 中文文档翻译计划 +# React 中文文档翻译计划 ![CircleCI](https://circleci.com/gh/discountry/react.svg?&style=shield&circle-token=4fc9b6b97cb8d5d19ad88cdd40ba8d5f1ccdd2b0) ## Notice > This is not the official react repository. We've been working on translating the official react docs in Chinese. Because of the modification of original docs markdown files, this branch can not be merged to the [reactjs/reactjs.org](https://github.com/reactjs/reactjs.org) . -React 官方中文文档将基于此项目内容继续维护,请贡献者移步 [https://github.com/reactjs/zh-hans.reactjs.org](https://github.com/reactjs/zh-hans.reactjs.org) 参与翻译工作。 - ## 临时说明 本文档与 React 官方文档保持同步,请认准页脚**印记中文**的标识。不要被网络上一些盗用的过期文档误导。 @@ -34,6 +32,10 @@ React 官方中文文档将基于此项目内容继续维护,请贡献者移 React@16 的新版文档网站使用了 [Gatsby](https://github.com/gatsbyjs/gatsby) 静态站点生成器,站点对应文件均在 [`/src`](https://github.com/discountry/react/tree/master/src) 文件夹下,如果有对网站模板/样式/配置的改动,请直接编辑该目录下文件并提交 pr 即可。 +**为 React 官方贡献翻译** + +React 官网会在将来支持多语言功能,目前官方已经发起了翻译项目,你可以在 [React on Crowdin](https://crowdin.com/project/react) 贡献翻译。 + ## Contributors 感谢所有[参与翻译的同学](https://github.com/discountry/react/graphs/contributors)。是大家的开源精神和辛勤工作让文档的翻译得以如此顺利迅速进行。 diff --git a/README_en.md b/README_en.md old mode 100644 new mode 100755 diff --git a/content/404.md b/content/404.md old mode 100644 new mode 100755 diff --git a/content/authors.yml b/content/authors.yml index 3defa4f500..bf79d29cf8 100644 --- a/content/authors.yml +++ b/content/authors.yml @@ -85,6 +85,3 @@ wincent: zpao: name: Paul O’Shannessy url: https://twitter.com/zpao -tomocchino: - name: Tom Occhino - url: https://twitter.com/tomocchino diff --git a/content/blog/2013-06-02-jsfiddle-integration.md b/content/blog/2013-06-02-jsfiddle-integration.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-06-05-why-react.md b/content/blog/2013-06-05-why-react.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-06-12-community-roundup.md b/content/blog/2013-06-12-community-roundup.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-06-19-community-roundup-2.md b/content/blog/2013-06-19-community-roundup-2.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-06-21-react-v0-3-3.md b/content/blog/2013-06-21-react-v0-3-3.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-06-27-community-roundup-3.md b/content/blog/2013-06-27-community-roundup-3.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-02-react-v0-4-autobind-by-default.md b/content/blog/2013-07-02-react-v0-4-autobind-by-default.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-03-community-roundup-4.md b/content/blog/2013-07-03-community-roundup-4.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-11-react-v0-4-prop-validation-and-default-values.md b/content/blog/2013-07-11-react-v0-4-prop-validation-and-default-values.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-17-react-v0-4-0.md b/content/blog/2013-07-17-react-v0-4-0.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-23-community-roundup-5.md b/content/blog/2013-07-23-community-roundup-5.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-26-react-v0-4-1.md b/content/blog/2013-07-26-react-v0-4-1.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-07-30-use-react-and-jsx-in-ruby-on-rails.md b/content/blog/2013-07-30-use-react-and-jsx-in-ruby-on-rails.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-08-05-community-roundup-6.md b/content/blog/2013-08-05-community-roundup-6.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-08-19-use-react-and-jsx-in-python-applications.md b/content/blog/2013-08-19-use-react-and-jsx-in-python-applications.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-08-26-community-roundup-7.md b/content/blog/2013-08-26-community-roundup-7.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-09-24-community-roundup-8.md b/content/blog/2013-09-24-community-roundup-8.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-10-16-react-v0.5.0.md b/content/blog/2013-10-16-react-v0.5.0.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-10-29-react-v0-5-1.md b/content/blog/2013-10-29-react-v0-5-1.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-10-3-community-roundup-9.md b/content/blog/2013-10-3-community-roundup-9.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-11-06-community-roundup-10.md b/content/blog/2013-11-06-community-roundup-10.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-11-18-community-roundup-11.md b/content/blog/2013-11-18-community-roundup-11.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-12-18-react-v0.5.2-v0.4.2.md b/content/blog/2013-12-18-react-v0.5.2-v0.4.2.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-12-19-react-v0.8.0.md b/content/blog/2013-12-19-react-v0.8.0.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-12-23-community-roundup-12.md b/content/blog/2013-12-23-community-roundup-12.md old mode 100644 new mode 100755 diff --git a/content/blog/2013-12-30-community-roundup-13.md b/content/blog/2013-12-30-community-roundup-13.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-01-02-react-chrome-developer-tools.md b/content/blog/2014-01-02-react-chrome-developer-tools.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-01-06-community-roundup-14.md b/content/blog/2014-01-06-community-roundup-14.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-02-05-community-roundup-15.md b/content/blog/2014-02-05-community-roundup-15.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-02-15-community-roundup-16.md b/content/blog/2014-02-15-community-roundup-16.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-02-16-react-v0.9-rc1.md b/content/blog/2014-02-16-react-v0.9-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-02-20-react-v0.9.md b/content/blog/2014-02-20-react-v0.9.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-02-24-community-roundup-17.md b/content/blog/2014-02-24-community-roundup-17.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-03-14-community-roundup-18.md b/content/blog/2014-03-14-community-roundup-18.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-03-19-react-v0.10-rc1.md b/content/blog/2014-03-19-react-v0.10-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-03-21-react-v0.10.md b/content/blog/2014-03-21-react-v0.10.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-03-28-the-road-to-1.0.md b/content/blog/2014-03-28-the-road-to-1.0.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-04-04-reactnet.md b/content/blog/2014-04-04-reactnet.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-05-06-flux.md b/content/blog/2014-05-06-flux.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-05-29-one-year-of-open-source-react.md b/content/blog/2014-05-29-one-year-of-open-source-react.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-06-27-community-roundup-19.md b/content/blog/2014-06-27-community-roundup-19.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-07-13-react-v0.11-rc1.md b/content/blog/2014-07-13-react-v0.11-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-07-17-react-v0.11.md b/content/blog/2014-07-17-react-v0.11.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-07-25-react-v0.11.1.md b/content/blog/2014-07-25-react-v0.11.1.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-07-28-community-roundup-20.md b/content/blog/2014-07-28-community-roundup-20.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-07-30-flux-actions-and-the-dispatcher.md b/content/blog/2014-07-30-flux-actions-and-the-dispatcher.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-08-03-community-roundup-21.md b/content/blog/2014-08-03-community-roundup-21.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-09-03-introducing-the-jsx-specification.md b/content/blog/2014-09-03-introducing-the-jsx-specification.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-09-12-community-round-up-22.md b/content/blog/2014-09-12-community-round-up-22.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-09-16-react-v0.11.2.md b/content/blog/2014-09-16-react-v0.11.2.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-09-24-testing-flux-applications.md b/content/blog/2014-09-24-testing-flux-applications.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-10-14-introducing-react-elements.md b/content/blog/2014-10-14-introducing-react-elements.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-10-16-react-v0.12-rc1.md b/content/blog/2014-10-16-react-v0.12-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-10-17-community-roundup-23.md b/content/blog/2014-10-17-community-roundup-23.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-10-27-react-js-conf.md b/content/blog/2014-10-27-react-js-conf.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-10-28-react-v0.12.md b/content/blog/2014-10-28-react-v0.12.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-11-24-react-js-conf-updates.md b/content/blog/2014-11-24-react-js-conf-updates.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-11-25-community-roundup-24.md b/content/blog/2014-11-25-community-roundup-24.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-12-18-react-v0.12.2.md b/content/blog/2014-12-18-react-v0.12.2.md old mode 100644 new mode 100755 diff --git a/content/blog/2014-12-19-react-js-conf-diversity-scholarship.md b/content/blog/2014-12-19-react-js-conf-diversity-scholarship.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-01-27-react-v0.13.0-beta-1.md b/content/blog/2015-01-27-react-v0.13.0-beta-1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-02-18-react-conf-roundup-2015.md b/content/blog/2015-02-18-react-conf-roundup-2015.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-02-20-introducing-relay-and-graphql.md b/content/blog/2015-02-20-introducing-relay-and-graphql.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-02-24-react-v0.13-rc1.md b/content/blog/2015-02-24-react-v0.13-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-02-24-streamlining-react-elements.md b/content/blog/2015-02-24-streamlining-react-elements.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-03-react-v0.13-rc2.md b/content/blog/2015-03-03-react-v0.13-rc2.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-04-community-roundup-25.md b/content/blog/2015-03-04-community-roundup-25.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-10-react-v0.13.md b/content/blog/2015-03-10-react-v0.13.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-16-react-v0.13.1.md b/content/blog/2015-03-16-react-v0.13.1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-19-building-the-facebook-news-feed-with-relay.md b/content/blog/2015-03-19-building-the-facebook-news-feed-with-relay.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-26-introducing-react-native.md b/content/blog/2015-03-26-introducing-react-native.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-03-30-community-roundup-26.md b/content/blog/2015-03-30-community-roundup-26.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-04-17-react-native-v0.4.md b/content/blog/2015-04-17-react-native-v0.4.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-04-18-react-v0.13.2.md b/content/blog/2015-04-18-react-v0.13.2.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-05-01-graphql-introduction.md b/content/blog/2015-05-01-graphql-introduction.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-05-08-react-v0.13.3.md b/content/blog/2015-05-08-react-v0.13.3.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-05-22-react-native-release-process.md b/content/blog/2015-05-22-react-native-release-process.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-06-12-deprecating-jstransform-and-react-tools.md b/content/blog/2015-06-12-deprecating-jstransform-and-react-tools.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-07-03-react-v0.14-beta-1.md b/content/blog/2015-07-03-react-v0.14-beta-1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-08-03-new-react-devtools-beta.md b/content/blog/2015-08-03-new-react-devtools-beta.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-08-11-relay-technical-preview.md b/content/blog/2015-08-11-relay-technical-preview.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-08-13-reacteurope-roundup.md b/content/blog/2015-08-13-reacteurope-roundup.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-09-02-new-react-developer-tools.md b/content/blog/2015-09-02-new-react-developer-tools.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-09-10-react-v0.14-rc1.md b/content/blog/2015-09-10-react-v0.14-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-09-14-community-roundup-27.md b/content/blog/2015-09-14-community-roundup-27.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-10-01-react-render-and-top-level-api.md b/content/blog/2015-10-01-react-render-and-top-level-api.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-10-07-react-v0.14.md b/content/blog/2015-10-07-react-v0.14.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-10-19-reactiflux-is-moving-to-discord.md b/content/blog/2015-10-19-reactiflux-is-moving-to-discord.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-10-28-react-v0.14.1.md b/content/blog/2015-10-28-react-v0.14.1.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-11-02-react-v0.14.2.md b/content/blog/2015-11-02-react-v0.14.2.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-11-18-react-v0.14.3.md b/content/blog/2015-11-18-react-v0.14.3.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-12-04-react-js-conf-2016-diversity-scholarship.md b/content/blog/2015-12-04-react-js-conf-2016-diversity-scholarship.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-12-16-ismounted-antipattern.md b/content/blog/2015-12-16-ismounted-antipattern.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-12-18-react-components-elements-and-instances.md b/content/blog/2015-12-18-react-components-elements-and-instances.md old mode 100644 new mode 100755 diff --git a/content/blog/2015-12-29-react-v0.14.4.md b/content/blog/2015-12-29-react-v0.14.4.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-01-08-A-implies-B-does-not-imply-B-implies-A.md b/content/blog/2016-01-08-A-implies-B-does-not-imply-B-implies-A.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-01-12-discontinuing-ie8-support.md b/content/blog/2016-01-12-discontinuing-ie8-support.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-02-19-new-versioning-scheme.md b/content/blog/2016-02-19-new-versioning-scheme.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-03-07-react-v15-rc1.md b/content/blog/2016-03-07-react-v15-rc1.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-03-16-react-v15-rc2.md b/content/blog/2016-03-16-react-v15-rc2.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-03-29-react-v0.14.8.md b/content/blog/2016-03-29-react-v0.14.8.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-04-07-react-v15.md b/content/blog/2016-04-07-react-v15.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-04-08-react-v15.0.1.md b/content/blog/2016-04-08-react-v15.0.1.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-07-11-introducing-reacts-error-code-system.md b/content/blog/2016-07-11-introducing-reacts-error-code-system.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-07-13-mixins-considered-harmful.md b/content/blog/2016-07-13-mixins-considered-harmful.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-07-22-create-apps-with-no-configuration.md b/content/blog/2016-07-22-create-apps-with-no-configuration.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-08-05-relay-state-of-the-state.md b/content/blog/2016-08-05-relay-state-of-the-state.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-09-28-our-first-50000-stars.md b/content/blog/2016-09-28-our-first-50000-stars.md old mode 100644 new mode 100755 diff --git a/content/blog/2016-11-16-react-v15.4.0.md b/content/blog/2016-11-16-react-v15.4.0.md old mode 100644 new mode 100755 diff --git a/content/blog/2017-04-07-react-v15.5.0.md b/content/blog/2017-04-07-react-v15.5.0.md old mode 100644 new mode 100755 index 943e1b572c..f901fadae6 --- a/content/blog/2017-04-07-react-v15.5.0.md +++ b/content/blog/2017-04-07-react-v15.5.0.md @@ -7,7 +7,7 @@ author: [acdlite] 最后,我们发布了React 15.5.0。 -### 新的弃用警告 {#new-deprecation-warnings} +### 新的弃用警告 最大的改变是我们将`React.PropTypes`和`React.createClass` 移到他们的自己的包。二者仍然可以通过主要的`React`独享访问,但是在开发模式下,使用其中的一个将在控制台上打印一个过时的弃用警告。这将会让之后代码大小有所优化。 @@ -19,7 +19,7 @@ author: [acdlite] 关于每一项新的弃用,我们已经提供了一份代码修改(codemod)以自动迁移你的代码。它们已可以利用来作为 [react-codemod](https://github.com/reactjs/react-codemod)项目的部分。 -### 从 React.PropTypes 迁移 {#migrating-from-reactproptypes} +### 从React.PropTypes迁移 属性类型是用于在开发期间对属性进行运行时校验的一项特性。我们已将内建的属性类型提取到一个独立的包中以反映是否并非每个人都会使用的事实。 @@ -64,7 +64,7 @@ jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js 你也可能考虑使用 [Flow](https://flow.org/)来静态地检查你的JavaScript代码类型,包括[React 组件](https://flow.org/en/docs/frameworks/react/#setup-flow-with-react-a-classtoc-idtoc-setup-flow-with-react-hreftoc-setup-flow-with-reacta). -### 从 React.crateClass 迁移 {#migrating-from-reactcreateclass} +### 从React.crateClass迁移 当React首次发布时,在JavaScript中并没有通用的方式创建类,因此我们提供我们一个自定义方法:`React.createClass`。 @@ -105,7 +105,7 @@ var Component = createReactClass({ jscodeshift -t react-codemod/transforms/class.js path/to/components ``` -### 不再支持的 React 附件 {#discontinuing-support-for-react-addons} +### 不再支持的React附件 我们将停止维护React附件包。真实地,大多数包已经有很长时间没有维护了。它们仍将持续继续工作,但我们建议尽快迁移以防止将来的破坏。 @@ -120,7 +120,7 @@ jscodeshift -t react-codemod/transforms/class.js path/to/components 我们也放弃对于`react-with-addons`UMD构建的支持。其将在React 16中被移除。 -### React 测试套件 {#react-test-utils} +### React测试套件 当前,React 测试套件位于`react-addons-test-utils`内。在15.5中,我们将其从包中独立出去,并将它们迁移至`react-dom/test-utils`: @@ -146,7 +146,7 @@ import { createRenderer } from 'react-test-renderer/shallow'; --- -## 感谢 {#acknowledgements} +## 感谢 特别感谢这些人转让npm包名称的所有权: @@ -156,7 +156,7 @@ import { createRenderer } from 'react-test-renderer/shallow'; --- -## 安装 {#installation} +## 安装 我们推荐使用[Yarn](https://yarnpkg.com/)或[npm](https://www.npmjs.com/)来管理前端依赖。若你是初次接触包管理器,[Yarn documentation](https://yarnpkg.com/en/docs/getting-started)是一个不错的起点。 @@ -195,11 +195,11 @@ npm install --save react@^15.5.0 react-dom@^15.5.0 --- -## 修改日志 {#changelog} +## 修改日志 -## 15.5.0 (April 7, 2017) {#1550-april-7-2017} +## 15.5.0 (April 7, 2017) -### React {#react} +### React * 为`React.createClass`增加一个独立的警告。将用户指向create-react-class。([@acdlite](https://github.com/acdlite) 在 [d9a4fa4](https://github.com/facebook/react/commit/d9a4fa4f51c6da895e1655f32255cf72c0fe620e)的提交) * 为`React.PropTypes`增加一个独立的警告。将用户指向prop-types。([@acdlite](https://github.com/acdlite) 在 [043845c](https://github.com/facebook/react/commit/043845ce75ea0812286bbbd9d34994bb7e01eb28)的提交) @@ -208,17 +208,17 @@ npm install --save react@^15.5.0 react-dom@^15.5.0 * 另一个关于Closure Compiler的修复。([@Shastel](https://github.com/Shastel) 在 [#8882](https://github.com/facebook/react/pull/8882)提的PR) * 为无效的元素类型警告增加组件栈信息。([@n3tr](https://github.com/n3tr) 在 [#8495](https://github.com/facebook/react/pull/8495)提的PR) -### React DOM {#react-dom} +### React DOM * 修正当在数字输入中回退时的Chrome bug。([@nhunzaker](https://github.com/nhunzaker) 在 [#7359](https://github.com/facebook/react/pull/7359)提的PR) * 增加`react-dom/test-utils`,暴露React测试套件。([@bvaughn](https://github.com/bvaughn)) -### React Test Renderer {#react-test-renderer} +### React Test Renderer * 修复子组件不会调用`componentWillUnmount`。([@gre](https://github.com/gre) 在 [#8512](https://github.com/facebook/react/pull/8512]提的PR) * 增加 `react-test-renderer/shallow`,暴露浅渲染器。 -### React Addons {#react-addons} +### React Addons * 最后一次发布附件;他们将不再被维护 * 移除`peerDependencies`以让附件能够无限期继续工作。([@acdlite](https://github.com/acdlite) 和 [@bvaughn](https://github.com/bvaughn) 在 [8a06cd7](https://github.com/facebook/react/commit/8a06cd7a786822fce229197cac8125a551e8abfa) 和 [67a8db3](https://github.com/facebook/react/commit/67a8db3650d724a51e70be130e9008806402678a)的提交) diff --git a/content/blog/2017-05-18-whats-new-in-create-react-app.md b/content/blog/2017-05-18-whats-new-in-create-react-app.md old mode 100644 new mode 100755 index bbbd39a4e2..c7664133aa --- a/content/blog/2017-05-18-whats-new-in-create-react-app.md +++ b/content/blog/2017-05-18-whats-new-in-create-react-app.md @@ -11,7 +11,7 @@ author: [gaearon] 新创建的项目会自动获得这些新的功能改进。 -### webpack 2 {#webpack-2} +### webpack 2 >*这个功能开发者是[@Timer](https://github.com/Timer) 在 [#1291](https://github.com/facebookincubator/create-react-app/pull/1291).* @@ -27,7 +27,7 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 未来,随着 ES6 模块相关生态系统的成熟,webpack 2 还提供了 [tree shaking](https://webpack.js.org/guides/tree-shaking/) 特性,可以通过去除冗余代码,优化打包后脚本的尺寸。 -### Runtime Error Overlay {#error-overlay} +### Runtime Error Overlay >*开发这个功能的是 [@Timer](https://github.com/Timer) 和 [@nicinabox](https://github.com/nicinabox) 在 [#1101](https://github.com/facebookincubator/create-react-app/pull/1101), [@bvaughn](https://github.com/bvaughn) 在 [#2201](https://github.com/facebookincubator/create-react-app/pull/2201).* @@ -43,7 +43,7 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 未来 Creat React App 还准备支持更多错误捕获。比如在React 16 版本发布之后,Creat React App 计划支持 React 组件调用栈的展示。 -### 默认支持渐进式 web 应用 {#progressive-web-apps-by-default} +### 默认支持渐进式web应用 >*这个功能的贡献者是 [@jeffposnick](https://github.com/jeffposnick) 在 [#1728](https://github.com/facebookincubator/create-react-app/pull/1728).* @@ -56,7 +56,7 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 在未来的几周我们会为这个主题增加 [更多文档](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app)。希望大家在答疑区畅所欲言,[积极提问](https://github.com/facebookincubator/create-react-app/issues/new) 。 -### Jest 20 {#jest-20} +### Jest 20 >*这个功能的贡献者是 [@rogeliog](https://github.com/rogeliog) 在 [#1614](https://github.com/facebookincubator/create-react-app/pull/1614) 和 [@gaearon](https://github.com/gaearon) 在 [#2171](https://github.com/facebookincubator/create-react-app/pull/2171).* @@ -68,7 +68,7 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 现在 Create React App 只需要做少量 Jest 的配置就可以生成覆盖率报告了。 -### 动态 import() 代码分割 {#code-splitting-with-dynamic-import} +### 动态import()代码分割 >*这个功能的贡献者是 [@Timer](https://github.com/Timer) 在 [#1538](https://github.com/facebookincubator/create-react-app/pull/1538) 和 [@tharakawj](https://github.com/tharakawj) 在 [#1801](https://github.com/facebookincubator/create-react-app/pull/1801).* @@ -78,7 +78,7 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 ![Creating chunks with dynamic import](../img/blog/cra-dynamic-import.gif) -### 更好的控制台输出 {#better-console-output} +### 更好的控制台输出 >*本功能开发者是 [@gaearon](https://github.com/gaearon) 于 [#2120](https://github.com/facebookincubator/create-react-app/pull/2120), [#2125](https://github.com/facebookincubator/create-react-app/pull/2125), 和 [#2161](https://github.com/facebookincubator/create-react-app/pull/2161)。* @@ -90,13 +90,13 @@ webpack 2 最引人注目的新特性就是其对 ES6 模块 的支持,可以 当代码错误报告出来了,我们将不再展示警告信息以便你集中注意力到更严重的问题上。错误和警告信息在生产环境下的展示也被优化了,而且构建错误的弹出字体跟浏览器字体匹配度更高了。 -### 别急... 还有干货! {#but-wait-theres-more} +### 别急... 还有干货! 虽然讲了很多,但是这个版本中还有许多未能介绍的新特性,比如 [environment-specific and local `.env` files](https://github.com/facebookincubator/create-react-app/pull/1344),[a lint rule against confusingly named globals](https://github.com/facebookincubator/create-react-app/pull/2130),[support for multiple proxies in development](https://github.com/facebookincubator/create-react-app/pull/1790), [a customizable browser launch script](https://github.com/facebookincubator/create-react-app/pull/1590)以及许多 bug 修复。 更多信息请参阅升级文档 [v1.0.0 发布详情](https://github.com/facebookincubator/create-react-app/releases/tag/v1.0.0)。 -### 致谢 {#acknowledgements} +### 致谢 这个发布版本是 React 社区的许多成员共同奋斗几个月的成果。我们旨在同时提升开发者的开发体验和用户的使用体验,因为我们坚信,这二者是互相补充携手并进的。 diff --git a/content/blog/2017-06-13-react-v15.6.0.md b/content/blog/2017-06-13-react-v15.6.0.md old mode 100644 new mode 100755 index 5bd3c90945..0769fbd6f0 --- a/content/blog/2017-06-13-react-v15.6.0.md +++ b/content/blog/2017-06-13-react-v15.6.0.md @@ -5,7 +5,7 @@ author: [flarnie] 今天我们发布了 React 15.6.0。由于我们在准备React 16.0,因此我们修复和清理了许多东西。此次发布将继续为后续铺路。 -## 提升Inputs {#improving-inputs} +## 提升Inputs 在React 15.6.0,输入框的`onChange`事件稍微可靠了点并能够处理更多边界条件,涵盖以下: @@ -18,7 +18,7 @@ author: [flarnie] 感谢[Jason Quense](https://github.com/jquense)以及其他帮助解决上述问题和提出PR的各位。 -## 更少嘈杂的弃用警告 {#less-noisy-deprecation-warnings} +## 更少嘈杂的弃用警告 我们还为之后的弃用引入了一系列新的警告。这些并不会影响大多数用户,更多细节可以查看下面的修改日志。 @@ -26,7 +26,7 @@ author: [flarnie] --- -## 安装 {#installation} +## 安装 我们推荐使用 [Yarn](https://yarnpkg.com/) 或 [npm](https://www.npmjs.com/) 来管理前端依赖。若你是初次接触包管理器,[Yarn 文档](https://yarnpkg.com/en/docs/getting-started)是一个不错的起点。 @@ -65,18 +65,18 @@ npm install --save react@^15.6.0 react-dom@^15.6.0 ------------ -## 修改日志 {#changelog} +## 修改日志 -## 15.6.0 (June 13, 2017) {#1560-june-13-2017} +## 15.6.0 (June 13, 2017) -### React {#react} +### React * 采用`console.warn`而不是`console.error`来降级处理弃用警告。([@flarnie](https://github.com/flarnie) 在 [#9753](https://github.com/facebook/react/pull/9753) 的提交) * 为`React.createClass`增加弃用警告。将用户指向`create-react-class`。([@flarnie](https://github.com/flarnie) 在 [#9771](https://github.com/facebook/react/pull/9771) 的提交) * 增加弃用警告并为`React.DOM`工厂辅助方法分离为新模块。([@nhunzaker](https://github.com/nhunzaker) 在 [#8356](https://github.com/facebook/react/pull/8356) 的提交) * `React.createMixin`的弃用警告辅助方法将不再使用。([@aweary](https://github.com/aweary) 在 [#8853](https://github.com/facebook/react/pull/8853) 的提交) -### React DOM {#react-dom} +### React DOM * 在`style`属性中增加CSS变量支持。 ([@aweary](https://github.com/aweary) 在 [#9302](https://github.com/facebook/react/pull/9302) 的提交) * 增加CSS网格(Grid)样式属性支持。([@ericsakmar](https://github.com/ericsakmar) 在 [#9185](https://github.com/facebook/react/pull/9185) 的提交) @@ -84,12 +84,3 @@ npm install --save react@^15.6.0 react-dom@^15.6.0 * 修复在某些输入场景下`onChange`未触发的问题。([@jquense](https://github.com/jquense) 在 [#8575](https://github.com/facebook/react/pull/8575) 的提交) * 修复控制数字输入框错误允许期间的异常。([@nhunzaker](https://github.com/nhunzaker) 在 [#9584](https://github.com/facebook/react/pull/9584) 的提交) * 修复性能记录(performance entry)被清除的bug。([@chrisui](https://github.com/chrisui) 在 [#9451](https://github.com/facebook/react/pull/9451) 的提交) - -### React Addons {#react-addons} - -* Fix AMD support for addons depending on `react`. ([@flarnie](https://github.com/flarnie) in [#9919](https://github.com/facebook/react/issues/9919)) -* Fix `isMounted()` to return `true` in `componentWillUnmount`. ([@mridgway](https://github.com/mridgway) in [#9638](https://github.com/facebook/react/issues/9638)) -* Fix `react-addons-update` to not depend on native `Object.assign`. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937)) -* Remove broken Google Closure Compiler annotation from `create-react-class`. ([@gaearon](https://github.com/gaearon) in [#9933](https://github.com/facebook/react/pull/9933)) -* Remove unnecessary dependency from `react-linked-input`. ([@gaearon](https://github.com/gaearon) in [#9766](https://github.com/facebook/react/pull/9766)) -* Point `react-addons-(css-)transition-group` to the new package. ([@gaearon](https://github.com/gaearon) in [#9937](https://github.com/facebook/react/pull/9937)) diff --git a/content/blog/2017-07-26-error-handle-in-react-16.md b/content/blog/2017-07-26-error-handle-in-react-16.md new file mode 100755 index 0000000000..c742295bd3 --- /dev/null +++ b/content/blog/2017-07-26-error-handle-in-react-16.md @@ -0,0 +1,116 @@ +--- +title: "Error Handle in React 16" +author: [gaearon] +--- + +随着React 16发布在即,我们打算介绍一些在组件内部React如何处理JavaScript错误。这些改变包含在React 16的beta版本中,并将成为React 16的一部分。 + +**顺便一提,[你可以尝试我们刚发布了React 16的第一个测试版本!](https://github.com/facebook/react/issues/10294)** + +## React 15及之前的行为 + +过去,组件内部的JavaScript异常曾经常阻断了React内部状态并导致其在下一次渲染时[触发了隐藏的错误](https://github.com/facebook/react/issues/6895)。这些错误常常是由应用程序代码中的早期错误所引起的,但React并未提供一种在组件里优雅处理的方式,也不会从异常中回复。 + +## 错误边界介绍 + +UI部分的JavaScript异常不应阻断整个应用。为了为React用户解决这一问题,React 16引入了"错误边界(error boundary")"这一新概念。 + +错误边界作为React组件,用以**捕获在子组件树种任何地方的JavaScript异常,打印这些错误,并展示备用UI**而非让组件树崩溃。错误边界会捕获渲染期间,在生命周期方法中以及在其整个树的构造函数中的异常。 + +若定义一个称为`componentDidCatch(error, info)`的新生命周期方法,则类组件将成为错误边界: + +```javascript +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + componentDidCatch(error, info) { + // Display fallback UI + this.setState({ hasError: true }); + // You can also log the error to an error reporting service + logErrorToMyService(error, info); + } + + render() { + if (this.state.hasError) { + // You can render any custom fallback UI + return

Something went wrong.

; + } + return this.props.children; + } +} +``` + +而后可作为一个正常组件进行使用: + +```javascript + + + +``` + +`componentDidCatch()`方法的作用类似于JavaScript的`catch {}`,但仅针对组件。仅有类组件可以成为错误边界。实际上,大多数时间你会想仅声明一次错误边界组件并在整个应用中使用。 + +注意,**错误边界仅可以捕获树中后代的组件错误**。一个错误边界无法捕获其自身的错误。若错误边界尝试渲染错误信息失败,则该错误会传递至上方最接近的错误边界。而这也类似JavaScript中的`catch {}`块的工作方式。 + +## Live Demo + +查看[在React 16测试版](https://github.com/facebook/react/issues/10294)中[关于如何声明和使用错误边界的例子](https://codepen.io/gaearon/pen/wqvxGa?editors=0010)。 + +## 放置错误边界 + +错误边界的粒度完全取决于你。你可能将其包装在顶层路由组件中并为用户展示"内部异常(Something went wrong)"的信息,类似于服务端框架处理崩溃。你可能也会在错误边界包装一些内部组件用以保护不会让应用的余下部分不会崩溃。 + +## 未捕获错误的新行为 + +这一改变有一个重要的意义。**作为React 16中不是由错误边界引起的错误将会使得整个React组件树被卸载。** + +我们曾争论这一决定,但在我们的经验中,将损坏的UI留在那里要比完全移除它要糟糕得多。例如,在类似Messenger这样的产品中留下可见的损坏的UI可能会导致一些人将信息发送给错误的人。类似地,对于支付应用来说显示错误的金额要比什么都不显示糟糕得多。 + + +这一改变意味着随着迁移至React 16,你们将会发现之前未留意过的应用程序存在的崩溃。增加错误边界能够让你在发生异常时提供更好的用户体验。 + +例如,Facebook Messenger将边栏,信息面板,会话日志以及消息输入的内容包装到单独的错误边界中。若其中某一个组件的UI崩溃了,其余的仍能正常交互。 + +我们也鼓励你使用JS错误报告服务(或自己构建)以让你能够了解在产品中产生的未处理的异常,并修复它们。 + +## 组件栈追踪 + +React 16会打印所有在开发环节中发生在渲染过程的错误到控制台,即使应用程序意外地将他们吞了。除了错误信息和JavaScript堆栈,其还提供了组件栈追踪。闲杂你可以在组件树中精确地查看错误产生的地方: + +Component stack traces in error message + +你也可以在组件堆栈中查看文件名和行数。这一功能在[Create React App 项目](https://github.com/facebookincubator/create-react-app)中默认开启: + +Component stack traces with line numbers in error message + +若你不使用Create React App,你可以手动添加[该插件](https://www.npmjs.com/package/babel-plugin-transform-react-jsx-source) 到你的Babel配置中。注意其仅能在开发环境中使用并**禁止在生产环境中使用。** + +## 为何不使用`try` / `catch`? + +`try` / `catch` 很好但其仅适用于命令式的代码: + +```javascript +try { + showButton(); +} catch (error) { + // ... +} +``` + +然而,React组件是声明式的,并指定了什么应该被渲染: + +```javascript + ); } ``` -在这里, `useState`是一个*钩子(Hook)* (稍后我们将会谈及它的含义)。我们在一个函数式组件中调用它,为这个组件增加一些内部的状态。React将会在下一次渲染前保存此状态。 `useState`返回一对值:*当前*的状态(state value)和一个可以更新状态的函数。你可以在事件处理程序(event handler)中或其他地方调用这个函数。 它与类组件中的`this.setState`类似,但不能将新旧状态进行合并。(我们在[使用状态钩子](/docs/hooks-state.html)中展示了一个将`useState`和`this.state`进行对比的例子。) +Here, `useState` is a *Hook* (we'll talk about what this means in a moment). We call it inside a function component to add some local state to it. React will preserve this state between re-renders. `useState` returns a pair: the *current* state value and a function that lets you update it. You can call this function from an event handler or somewhere else. It's similar to `this.setState` in a class, except it doesn't merge the old and new state together. (We'll show an example comparing `useState` to `this.state` in [Using the State Hook](/docs/hooks-state.html).) -`useState`唯一的参数就是初始状态(initial state)。在上面的例子中,因为我们的计数器从零开始所以它是`0`。这里的状态与`this.state`不同,它不必是一个对象-- 如果你想这么做,当然也可以。初始状态参数只在第一次渲染中被使用。 +The only argument to `useState` is the initial state. In the example above, it is `0` because our counter starts from zero. Note that unlike `this.state`, the state here doesn't have to be an object -- although it can be if you want. The initial state argument is only used during the first render. -#### 声明多个状态变量 +#### Declaring multiple state variables -你可以在一个组件中多次使用状态钩子: +You can use the State Hook more than once in a single component: ```js function ExampleWithManyStates() { - // 声明多个状态变量! + // Declare multiple state variables! const [age, setAge] = useState(42); const [fruit, setFruit] = useState('banana'); const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]); @@ -58,25 +58,25 @@ function ExampleWithManyStates() { } ``` -通过调用`useState`我们声明了一些状态变量,我们可以使用[数组解构](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring)语法赋予这些状态变量不同的名字。这些名字不是`useState` API的一部分。 相反,当你多次调用`useState`时,React假定你在每一次渲染中以相同的顺序调用它们。我们会在之后再来解释为什么这样可以运行以及在什么时候起作用。 +The [array destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring) syntax lets us give different names to the state variables we declared by calling `useState`. These names aren't a part of the `useState` API. Instead, React assumes that if you call `useState` many times, you do it in the same order during every render. We'll come back to why this works and when this is useful later. -#### 但是什么是钩子(Hook)? +#### But what is a Hook? -钩子是可以让你与React状态以及函数式组件的生命周期特性"挂钩"的函数。钩子是为了让你抛弃类使用React的,所以它不能在类中运行。(我们[不推荐](/docs/hooks-intro.html#gradual-adoption-strategy)你立即重写已经存在的组件,但是如果你喜欢的话可以在新的组件中开始使用钩子。) +Hooks are functions that let you "hook into" React state and lifecycle features from function components. Hooks don't work inside classes -- they let you use React without classes. (We [don't recommend](/docs/hooks-intro.html#gradual-adoption-strategy) rewriting your existing components overnight but you can start using Hooks in the new ones if you'd like.) -React提供了少量内置的钩子,如`useState`。你也可以创建自己的钩子在不同的组件之间复用有状态的行为。我们先来看一下内置的钩子。 +React provides a few built-in Hooks like `useState`. You can also create your own Hooks to reuse stateful behavior between different components. We'll look at the built-in Hooks first. ->详细解释 +>Detailed Explanation > ->你可以在这个页面上了解到更多关于状态钩子的信息: [使用状态钩子](/docs/hooks-state.html)。 +>You can learn more about the State Hook on a dedicated page: [Using the State Hook](/docs/hooks-state.html). -## ⚡️ 副作用钩子(Effect Hook) +## ⚡️ Effect Hook -你可能之前已经在React中执行过获取数据,订阅或者手动改变DOM。我们称这些操作为"副作用(side effects)"(或者简称为"作用(effects)"),因为它们可以影响其他的组件并且不能在渲染中完成。 +You've likely performed data fetching, subscriptions, or manually changing the DOM from React components before. We call these operations "side effects" (or "effects" for short) because they can affect other components and can't be done during rendering. -副作用钩子, `useEffect`, 为函数式组件带来执行副作用的能力。它与类组件中的`componentDidMount` ,`componentDidUpdate`和 `componentWillUnmount`具有相同的用途,但是被统一为一个API。(我们在[使用副作用钩子](/docs/hooks-effect.html)中展示了一个将`useEffect`和这些方法进行对比的例子。) +The Effect Hook, `useEffect`, adds the ability to perform side effects from a function component. It serves the same purpose as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` in React classes, but unified into a single API. (We'll show examples comparing `useEffect` to these methods in [Using the Effect Hook](/docs/hooks-effect.html).) -举个例子,这个组件在React更新DOM之后设置文档的标题: +For example, this component sets the document title after React updates the DOM: ```js{1,6-10} import { useState, useEffect } from 'react'; @@ -84,9 +84,9 @@ import { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); - // 类似于 componentDidMount 和 componentDidUpdate: + // Similar to componentDidMount and componentDidUpdate: useEffect(() => { - // 使用浏览器API更新文档标题 + // Update the document title using the browser API document.title = `You clicked ${count} times`; }); @@ -101,9 +101,9 @@ function Example() { } ``` -当你调用`useEffect`,就是告诉React在刷新DOM之后运行你的副作用函数。副作用函数在组件中声明,所以可以使用组件的状态(state)和属性(props)。React默认在每一次渲染后运行副作用函数——*包括*第一次渲染。(与类组件的生命周期函数的对比请看[使用副作用钩子](/docs/hooks-effect.html)。) +When you call `useEffect`, you're telling React to run your "effect" function after flushing changes to the DOM. Effects are declared inside the component so they have access to its props and state. By default, React runs the effects after every render -- *including* the first render. (We'll talk more about how this compares to class lifecycles in [Using the Effect Hook](/docs/hooks-effect.html).) -副作用函数可以通过返回一个函数来指定如何"回收"它们。举个例子,这个组件使用了一个副作用函数来订阅一个朋友的在线状态,通过取消订阅来回收: +Effects may also optionally specify how to "clean up" after them by returning a function. For example, this component uses an effect to subscribe to a friend's online status, and cleans up by unsubscribing from it: ```js{10-16} import { useState, useEffect } from 'react'; @@ -130,9 +130,9 @@ function FriendStatus(props) { } ``` -在这个例子中,当组件被卸载时,React会在由随后的渲染引起的副作用函数运行之前取消对`ChatAPI`的订阅。(如果有需要的话,可以用这个方法[告诉React跳过重订阅](/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects)当传给`ChatAPI`的`props.friend.id`没有改变时。) +In this example, React would unsubscribe from our `ChatAPI` when the component unmounts, as well as before re-running the effect due to a subsequent render. (If you want, there's a way to [tell React to skip re-subscribing](/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects) if the `props.friend.id` we passed to `ChatAPI` didn’t change.) -像使用`useState`一样,你可以在一个组件中使用多个副作用: +Just like with `useState`, you can use more than a single effect in a component: ```js{3,8} function FriendStatusWithCounter(props) { @@ -155,32 +155,32 @@ function FriendStatusWithCounter(props) { // ... ``` -有了钩子,你可以在组件中按照代码块的相关性组织副作用,而不是基于生命周期方法强制进行切分。 +Hooks let you organize side effects in a component by what pieces are related (such as adding and removing a subscription), rather than forcing a split based on lifecycle methods. ->详细解释 +>Detailed Explanation > ->你可以在这个页面上了解到更多关于`useEffect`的信息: [使用副作用钩子](/docs/hooks-effect.html)。 +>You can learn more about `useEffect` on a dedicated page: [Using the Effect Hook](/docs/hooks-effect.html). -## ✌️ 钩子的使用规则 +## ✌️ Rules of Hooks -钩子就是强制实现了两条额外规则的Javascript函数: +Hooks are JavaScript functions, but they impose two additional rules: -* 只能在*顶层*调用钩子。不要在循环,控制流和嵌套的函数中调用钩子。 -* 只能*从React的函数式组件中*调用钩子。不要在常规的JavaScript函数中调用钩子。(此外,你也可以在你的自定义钩子中调用钩子。我们马上就会讲到它。) +* Only call Hooks **at the top level**. Don’t call Hooks inside loops, conditions, or nested functions. +* Only call Hooks **from React function components**. Don’t call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks -- your own custom Hooks. We'll learn about them in a moment.) -我们提供了一个[语法检查插件](https://www.npmjs.com/package/eslint-plugin-react-hooks)以自动执行这些规则。我们能够理解开发者在一开始可能会对这些规则感到困惑或束手束脚,但它们正是保证钩子正确运行的基石。 +We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically. We understand these rules might seem limiting or confusing at first, but they are essential to making Hooks work well. ->详细解释 +>Detailed Explanation > ->你可以在这个页面上了解到更多关于这些规则的信息: [钩子的使用规则](/docs/hooks-rules.html)。 +>You can learn more about these rules on a dedicated page: [Rules of Hooks](/docs/hooks-rules.html). -## 💡 构建你自己的钩子 +## 💡 Building Your Own Hooks -有时你希望在组件之间复用一些状态逻辑。在之前有两种流行的解决方案:[高阶组件](/docs/higher-order-components.html) and [渲染属性](/docs/render-props.html)。现在你可以利用自定义钩子做到这些而不用在你的组件树中添加更多的组件。 +Sometimes, we want to reuse some stateful logic between components. Traditionally, there were two popular solutions to this problem: [higher-order components](/docs/higher-order-components.html) and [render props](/docs/render-props.html). Custom Hooks let you do this, but without adding more components to your tree. -在此之前,我们展示了一个`FriendStatus` 组件,它可以调用`useState`和`useEffect`钩子来订阅一个朋友的在线状态。假设我们想要在其他的组件中复用这个订阅逻辑。 +Earlier on this page, we introduced a `FriendStatus` component that calls the `useState` and `useEffect` Hooks to subscribe to a friend's online status. Let's say we also want to reuse this subscription logic in another component. -首先,我们要把这个逻辑抽取到名为`useFriendStatus`的自定义钩子中: +First, we'll extract this logic into a custom Hook called `useFriendStatus`: ```js{3} import { useState, useEffect } from 'react'; @@ -203,9 +203,9 @@ function useFriendStatus(friendID) { } ``` -这个钩子需要一个`friendID`作为参数,返回你的朋友是否在线。 +It takes `friendID` as an argument, and returns whether our friend is online. -现在,我们可以同时在两个组件中使用它: +Now we can use it from both components: ```js{2} @@ -231,19 +231,19 @@ function FriendListItem(props) { } ``` -两个组件中的状态是完全独立的。钩子只复用状态逻辑而不是状态本身。事实上,每一次调用钩子都会得到一个完全孤立的状态——所以你甚至可以在同一个组件中使用两次相同的自定义钩子。 +The state of these components is completely independent. Hooks are a way to reuse *stateful logic*, not state itself. In fact, each *call* to a Hook has a completely isolated state -- so you can even use the same custom Hook twice in one component. -自定义钩子更多的是一个约定而不是特性。如果一个函数的名字以 "`use`" 开头并且调用了其他的钩子,我们就称它为自定义钩子。`useSomething`的命名约定方便语法检查插件找到代码中钩子的错误使用。 +Custom Hooks are more of a convention than a feature. If a function's name starts with "`use`" and it calls other Hooks, we say it is a custom Hook. The `useSomething` naming convention is how our linter plugin is able to find bugs in the code using Hooks. -自定义钩子可以覆盖非常多的用例,像表单处理,动画,声明式订阅,定时器,还有很多我们还没有考虑到的。我们非常激动能够看到React社区提出的自定义钩子。 +You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven't considered. We are excited to see what custom Hooks the React community will come up with. ->详细解释 +>Detailed Explanation > ->你可以在专门的页面上了解到更多关于自定义钩子的信息:[构建你自己的钩子](/docs/hooks-custom.html)。 +>You can learn more about custom Hooks on a dedicated page: [Building Your Own Hooks](/docs/hooks-custom.html). -## 🔌 其他钩子 +## 🔌 Other Hooks -还有一些不太常用的内置钩子,也许你会觉得非常有用。使用[`useContext`](/docs/hooks-reference.html#usecontext)可以订阅React context而不用引入嵌套: +There are a few less commonly used built-in Hooks that you might find useful. For example, [`useContext`](/docs/hooks-reference.html#usecontext) lets you subscribe to React context without introducing nesting: ```js{2,3} function Example() { @@ -251,24 +251,24 @@ function Example() { const theme = useContext(ThemeContext); // ... } -``` +``` -[`useReducer`](/docs/hooks-reference.html#usereducer)则允许你使用一个reducer来管理一个复杂组件的局部状态(local state): +And [`useReducer`](/docs/hooks-reference.html#usereducer) lets you manage local state of complex components with a reducer: ```js{2} function Todos() { const [todos, dispatch] = useReducer(todosReducer); // ... -``` +``` ->详细解释 +>Detailed Explanation > ->你可以在这个页面上了解到所有的内置钩子: [钩子API参考](/docs/hooks-reference.html)。 +>You can learn more about all the built-in Hooks on a dedicated page: [Hooks API Reference](/docs/hooks-reference.html). -## 下一步 +## Next Steps -噢,太快了!如果有些地方没有讲清楚或者你想了解更多细节,你可以阅读下一页,从[状态钩子](/docs/hooks-state.html)这篇文档开始。 +Phew, that was fast! If some things didn't quite make sense or you'd like to learn more in detail, you can read the next pages, starting with the [State Hook](/docs/hooks-state.html) documentation. -你也可以查看[钩子API参考](/docs/hooks-reference.html)和[钩子常见问题](/docs/hooks-faq.html)。 +You can also check out the [Hooks API reference](/docs/hooks-reference.html) and the [Hooks FAQ](/docs/hooks-faq.html). -最后,不要错过[介绍页面](/docs/hooks-intro.html),这里解释了为什么我们要引入钩子以及我们如何同时使用类和钩子,而无需重写我们的应用。 +Finally, don't miss the [introduction page](/docs/hooks-intro.html) which explains *why* we're adding Hooks and how we'll start using them side by side with classes -- without rewriting our apps. diff --git a/content/docs/hooks-state.md b/content/docs/hooks-state.md index f71cbc70aa..72cdad8acd 100644 --- a/content/docs/hooks-state.md +++ b/content/docs/hooks-state.md @@ -6,12 +6,10 @@ next: hooks-effect.html prev: hooks-overview.html --- -*Hooks* is a new feature proposal that lets you use state and other React features without writing a class. They're currently in React v16.7.0-alpha and being discussed in [an open RFC](https://github.com/reactjs/rfcs/pull/68). - -*Hooks* 是一个新的特性(提案)用来在不书写class的情况下处理组件的状态. 已经部署在最新的React v16.7.0-alpha版本中,这里有关于它的讨论 [an open RFC](https://github.com/reactjs/rfcs/pull/68). +*Hooks* are a new feature proposal that lets you use state and other React features without writing a class. They're currently in React v16.7.0-alpha and being discussed in [an open RFC](https://github.com/reactjs/rfcs/pull/68). The [previous page](/docs/hooks-intro.html) introduced Hooks with this example: -下面这一页介绍了Hooks的一个示例 + ```js{4-5} import { useState } from 'react'; @@ -31,9 +29,9 @@ function Example() { ``` We'll start learning about Hooks by comparing this code to an equivalent class example. -我们通过比较类声明组件的方式和函数声明的方式来学习Hooks. + ## Equivalent Class Example -## 这是一个等价的类声明的组件 + If you used classes in React before, this code should look familiar: ```js @@ -59,21 +57,14 @@ class Example extends React.Component { ``` The state starts as `{ count: 0 }`, and we increment `state.count` when the user clicks a button by calling `this.setState()`. We'll use snippets from this class throughout the page. -这个状态从`{ count: 0 }`开始,然后在用户点击按钮的时候通过`this.setState()`增加 `state.count`,我们将在这一整页中使用这个代码段。 + >Note > >You might be wondering why we're using a counter here instead of a more realistic example. This is to help us focus on the API while we're still making our first steps with Hooks. ->注意 -> ->你可能疑惑为什么我们要使用counter而不是一个更实际的例子,因为我们现在的目的是集中讨论使用钩子的第一步,它的API - ## Hooks and Function Components As a reminder, function components in React look like this: -## Hooks和函数式组件 - -提醒一下,React函数组件是这个样子 ```js const Example = (props) => { @@ -82,7 +73,7 @@ const Example = (props) => { } ``` -或者: +or this: ```js function Example(props) { @@ -94,15 +85,11 @@ function Example(props) { You might have previously known these as "stateless components". We're now introducing the ability to use React state from these, so we prefer the name "function components". Hooks **don't** work inside classes. But you can use them instead of writing classes. -你可能之前使用过无状态组件,而现在要讨论的是在这里使用React的state,所以更适合叫"函数式组件". -Hooks 在class声明中**无法使用**,但是你可以使用它来代替类声明 ## What's a Hook? Our new example starts by importing the `useState` Hook from React: -## 什么是Hook -我们的例子是通过从React中导入一个 `useState` 钩子来开始的。 ```js{1} import { useState } from 'react'; @@ -113,23 +100,16 @@ function Example() { **What is a Hook?** A Hook is a special function that lets you "hook into" React features. For example, `useState` is a Hook that lets you add React state to function components. We'll learn other Hooks later. -**什么是钩子函数?**钩子函数是一个简单的函数,它允许你 "钩入" (hook into)React的特性,例如,`useState`是一个允许你在函数式组件中使用React的状态特性的钩子 **When would I use a Hook?** If you write a function component and realize you need to add some state to it, previously you had to convert it to a class. Now you can use a Hook inside the existing function component. We're going to do that right now! -**我该在什么时候使用钩子函数?**如果你编写了一个函数式组件,并且意识到你需要在上面添加一些必要的状态的时候使用它,当然,你必须从类声明中转变过来,现在你可以在已经存在的函数式组件中使用钩子函数(Hook),我们现在就开始。 + >Note: > >There are some special rules about where you can and can't use Hooks within a component. We'll learn them in [Rules of Hooks](/docs/hooks-rules.html). ->注意: -> ->有一些特殊的规则,你在组件的某些地方不可以使用钩子函数[Rules of Hooks](/docs/hooks-rules.html). ## Declaring a State Variable In a class, we initialize the `count` state to `0` by setting `this.state` to `{ count: 0 }` in the constructor: -## 声明一个状态变量 - -在类中的构造函数里面,我们通过设置`this.state`为`{count:0}`,从而初始化`count`状态为`0` ```js{4-6} class Example extends React.Component { constructor(props) { @@ -142,8 +122,6 @@ class Example extends React.Component { In a function component, we have no `this`, so we can't assign or read `this.state`. Instead, we call the `useState` Hook directly inside our component: -在一个函数式组件中,我们没有`this`,所以不用赋值或者读取`this.state`,与之相对应的,我们直接在组件中调用`useState`这个钩子函数 - ```js{4,5} import { useState } from 'react'; @@ -153,13 +131,13 @@ function Example() { ``` **What does calling `useState` do?** It declares a "state variable". Our variable is called `count` but we could call it anything else, like `banana`. This is a way to "preserve" some values between the function calls — `useState` is a new way to use the exact same capabilities that `this.state` provides in a class. Normally, variables "disappear" when the function exits but state variables are preserved by React. -**这个叫做`useState`的东西做了什么** 它声明了一个"状态变量",此时我们的变量叫做`count`,当然我们也可以给它任意取一个名字,像"香蕉""苹果"什么的,这是一种在函数调用中保存值的手段————`useState`是一个新的方法来实现`this.state`在class中所实现的相同的功能,通常情况下,变量在函数调用之后会"消失",但是在这里,React会将变量保存在自身。 + **What do we pass to `useState` as an argument?** The only argument to the `useState()` Hook is the initial state. Unlike with classes, the state doesn't have to be an object. We can keep a number or a string if that's all we need. In our example, we just want a number for how many times the user clicked, so pass `0` as initial state for our variable. (If we wanted to store two different values in state, we would call `useState()` twice.) -**如何通过`useState`来传递参数?**`useState`钩子唯一的参数就是初始化参数,不像在类组件中,函数式组件中的状态不是一个对象,如果需要的话,我们可以保存一个数字,或者一个字符串,在这个示例中,我们刚刚想要一个数字来显示用户点击的次数,所以设置`0`作为初始化状态(如果想要存储两个不同的值,必须再调一次`useState()`) + **What does `useState` return?** It returns a pair of values: the current state and a function that updates it. This is why we write `const [count, setCount] = useState()`. This is similar to `this.state.count` and `this.setState` in a class, except you get them in a pair. If you're not familiar with the syntax we used, we'll come back to it [at the bottom of this page](/docs/hooks-state.html#tip-what-do-square-brackets-mean). -**使用`useState`得到什么?**它会返回一对值:变化的状态变量和一个用来更新该状态的函数,也就是我们编写的`const [count, setCount] = useState()`,如果你对使用的语法不熟悉,可以返回[页面顶部](/docs/hooks-state.html#tip-what-do-square-brackets-mean). + Now that we know what the `useState` Hook does, our example should make more sense: -现在,已经知道了`useState`钩子的作用,我们的例子就更有意义了 + ```js{4,5} import { useState } from 'react'; @@ -169,39 +147,32 @@ function Example() { ``` We declare a state variable called `count`, and set it to `0`. React will remember its current value between re-renders, and provide the most recent one to our function. If we want to update the current `count`, we can call `setCount`. -我们声明了一个状态变量,名字是`count`,设置它的值是`0`,React会在重新渲染的时候记得它的值,提供最新的一个给函数,如果我们想要更新变化的`count`,直接调用`setCount。` + >Note > >You might be wondering: why is `useState` not named `createState` instead? > >"Create" wouldn't be quite accurate because the state is only created the first time our component renders. During the next renders, `useState` gives us the current state. Otherwise it wouldn't be "state" at all! There's also a reason why Hook names *always* start with `use`. We'll learn why later in the [Rules of Hooks](/docs/hooks-rules.html). ->注意 -> ->你可能会疑惑:为什么`useState`不叫做`createState`? -> ->"创建"(create)不太准确,因为状态只在第一次渲染的时候创建,在接下来的渲染过程中,`useState`返回的是变化后的值,另外,它已经不再是"状态",还有很多理由说明为何使用`use`,我们会在后面了解更多相关的信息[Rules of Hooks](/docs/hooks-rules.html). ## Reading State When we want to display the current count in a class, we read `this.state.count`: -## 渲染状态 -当我们想要在类组件中展示变化的count,我们读取`this.state.count`: ```js

You clicked {this.state.count} times

``` In a function, we can use `count` directly: -在函数中,我们可以直接使用`count` + ```js

You clicked {count} times

``` ## Updating State -## 更新状态 + In a class, we need to call `this.setState()` to update the `count` state: -在类中,我们需要调用`this.setState()`来更新`count` + ```js{1} - - ); -}; -``` +## 子代 -在上述例子中,`kind` 属性被安全地使用,不会传递到DOM中的 `