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/.scripts/gatsby-deploy.sh b/.scripts/gatsby-deploy.sh index 6a349818f3..1c6c070c3b 100644 --- a/.scripts/gatsby-deploy.sh +++ b/.scripts/gatsby-deploy.sh @@ -4,10 +4,6 @@ cd ~/project cp -r public/ ../public git config --global user.email "$GH_EMAIL"> /dev/null 2>&1 git config --global user.name "$GH_NAME"> /dev/null 2>&1 - -git add -A -git commit -m "from circleci" - git checkout gh-pages rm -rf * cp -r ../public/* ./ diff --git a/README.md b/README.md index bc31db6083..efc4b5e7f7 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ -# 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 官方文档保持同步,请认准页脚**印记中文**的标识。不要被网络上一些盗用的过期文档误导。 -**官网地址:**[https://react.docschina.org/](https://react.docschina.org/) +**官网地址:**[https://doc.react-china.org/](https://doc.react-china.org/) 如果你遇到网络问题,请移步: @@ -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..b5817e4781 100644 --- a/content/authors.yml +++ b/content/authors.yml @@ -18,7 +18,7 @@ clemmy: url: https://twitter.com/c8hoang Daniel15: name: Daniel Lo Nigro - url: https://d.sb/ + url: http://dan.cx/ fisherwebdev: name: Bill Fisher url: https://twitter.com/fisherwebdev @@ -73,9 +73,6 @@ sophiebits: steveluscher: name: Steven Luscher url: https://twitter.com/steveluscher -timer: - name: Joe Haddad - url: https://twitter.com/timer150 vjeux: name: Vjeux url: https://twitter.com/vjeux @@ -85,6 +82,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 + - - ); -} -``` - -Hooks [introduction](/docs/hooks-intro.html) and [overview](/docs/hooks-overview.html) are good places to start. Watch [these talks](https://www.youtube.com/watch?v=V-QO-KO90iQ) for a video introduction and a deep dive. The [FAQ](/docs/hooks-faq.html) should answer most of your further questions. To learn more about the motivation behind Hooks, you can read [this article](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889). Some of the rationale for the API design of Hooks is explained in [this RFC thread reply](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884). - -We have been dogfooding Hooks at Facebook since September. We don't expect major bugs in the implementation. Hooks are only available in the 16.7 alpha versions of React. Some of their API is expected to change in the final version (see the end of [this comment](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884) for details). It is possible that the minor release with Hooks might not be React 16.7. - -Hooks represent our vision for the future of React. They solve both problems that React users experience directly ("wrapper hell" of render props and higher-order components, duplication of logic in lifecycle methods), and the issues we've encountered optimizing React at scale (such as difficulties in inlining components with a compiler). Hooks don't deprecate classes. However, if Hooks are successful, it is possible that in a future *major* release class support might move to a separate package, reducing the default bundle size of React. - -**Status in React DOM:** The first version of `react` and `react-dom` supporting Hooks is `16.7.0-alpha.0`. We expect to publish more alphas over the next months (at the time of writing, the latest one is `16.7.0-alpha.2`). You can try them by installing `react@next` with `react-dom@next`. Don't forget to update `react-dom` -- otherwise Hooks won't work. - -**Status in React DOM Server:** The same 16.7 alpha versions of `react-dom` fully support Hooks with `react-dom/server`. - -**Status in React Native:** There is no officially supported way to try Hooks in React Native yet. If you're feeling adventurous, check out [this thread](https://github.com/facebook/react-native/issues/21967) for unofficial instructions. There is a known issue with `useEffect` firing too late which still needs to be solved. - -**Recommendation:** When you’re ready, we encourage you to start trying Hooks in new components you write. Make sure everyone on your team is on board with using them and familiar with this documentation. We don’t recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs). Read more about the adoption strategy [here](/docs/hooks-faq.html#adoption-strategy). - -### React 16.x (~Q2 2019): The One with Concurrent Mode - -*Concurrent Mode* lets React apps be more responsive by rendering component trees without blocking the main thread. It is opt-in and allows React to interrupt a long-running render (for example, rendering a new feed story) to handle a high-priority event (for example, text input or hover). Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections. - ->Note -> ->You might have previously heard Concurrent Mode being referred to as ["async mode"](/blog/2018/03/27/update-on-async-rendering.html). We've changed the name to Concurrent Mode to highlight React's ability to perform work on different priority levels. This sets it apart from other approaches to async rendering. - -```js -// Two ways to opt in: - -// 1. Part of an app (not final API) - - - - -// 2. Whole app (not final API) -ReactDOM.unstable_createRoot(domNode).render(); -``` - -There is no documentation written for the Concurrent Mode yet. It is important to highlight that the conceptual model will likely be unfamiliar at first. Documenting its benefits, how to use it efficiently, and its pitfalls is a high priority for us, and will be a prerequisite for calling it stable. Until then, [Andrew's talk](https://www.youtube.com/watch?v=ByBPyMBTzM0) is the best introduction available. - -Concurrent Mode is *much* less polished than Hooks. Some APIs aren't properly "wired up" yet and don't do what they're expected to. At the time of writing this post, we don't recommend using it for anything except very early experimentation. We don't expect many bugs in Concurrent Mode itself, but note that components that produce warnings in [``](https://reactjs.org/docs/strict-mode.html) may not work correctly. On a separate note, we've seen that Concurrent Mode *surfaces* performance problems in other code which can sometimes be mistaken for performance issues in Concurrent Mode itself. For example, a stray `setInterval(fn, 1)` call that runs every millisecond would have a worse effect in Concurrent Mode. We plan to publish more guidance about diagnosing and fixing issues like this as part of this release's documentation. - -Concurrent Mode is a big part of our vision for React. For CPU-bound work, it allows non-blocking rendering and keeps your app responsive while rendering complex component trees. That's demoed in the first part of [our JSConf Iceland talk](/blog/2018/03/01/sneak-peek-beyond-react-16.html). Concurrent Mode also makes Suspense better. It lets you avoid flickering a loading indicator if the network is fast enough. It's hard to explain without seeing so [Andrew's talk](https://www.youtube.com/watch?v=ByBPyMBTzM0) is the best resource available today. Concurrent Mode relies on a cooperative main thread [scheduler](https://github.com/facebook/react/tree/master/packages/scheduler), and we are [collaborating with the Chrome team](https://www.youtube.com/watch?v=mDdgfyRB5kg) to eventually move this functionality into the browser itself. - -**Status in React DOM:** A *very* unstable version of Concurrent Mode is available behind an `unstable_` prefix in React 16.6 but we don't recommend trying it unless you're willing to often run into walls or missing features. The 16.7 alphas include `React.ConcurrentMode` and `ReactDOM.createRoot` without an `unstable_` prefix, but we'll likely keep the prefix in 16.7, and only document and mark Concurrent Mode as stable in this future minor release. - -**Status in React DOM Server:** Concurrent Mode doesn't directly affect server rendering. It will work with the existing server renderer. - -**Status in React Native:** The current plan is to delay enabling Concurrent Mode in React Native until [React Fabric](https://github.com/react-native-community/discussions-and-proposals/issues/4) project is near completion. - -**Recommendation:** If you wish to adopt Concurrent Mode in the future, wrapping some component subtrees in [``](https://reactjs.org/docs/strict-mode.html) and fixing the resulting warnings is a good first step. In general it's not expected that legacy code would immediately be compatible. For example, at Facebook we mostly intend to use the Concurrent Mode in the more recently developed codebases, and keep the legacy ones running in the synchronous mode for the near future. - -### React 16.x (~mid 2019): The One with Suspense for Data Fetching - -As mentioned earlier, *Suspense* refers to React's ability to "suspend" rendering while components are waiting for something, and display a loading indicator. In the already shipped React 16.6, the only supported use case for Suspense is code splitting. In this future minor release, we'd like to provide officially supported ways to use it for data fetching too. We'll provide a reference implementation of a basic "React Cache" that's compatible with Suspense, but you can also write your own. Data fetching libraries like Apollo and Relay will be able to integrate with Suspense by following a simple specification that we'll document. - -```js -// React Cache for simple data fetching (not final API) -import {unstable_createResource} from 'react-cache'; - -// Tell React Cache how to fetch your data -const TodoResource = unstable_createResource(fetchTodo); - -function Todo(props) { - // Suspends until the data is in the cache - const todo = TodoResource.read(props.id); - return
  • {todo.title}
  • ; -} - -function App() { - return ( - // Same Suspense component you already use for code splitting - // would be able to handle data fetching too. - }> -
      - {/* Siblings fetch in parallel */} - - -
    -
    - ); -} - -// Other libraries like Apollo and Relay can also -// provide Suspense integrations with similar APIs. -``` - -There is no official documentation for how to fetch data with Suspense yet, but you can find some early information in [this talk](https://youtu.be/ByBPyMBTzM0?t=1312) and [this small demo](https://github.com/facebook/react/tree/master/fixtures/unstable-async/suspense). We'll write documentation for React Cache (and how to write your own Suspense-compatible library) closer to this React release, but if you're curious, you can find its very early source code [here](https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js). - -The low-level Suspense mechanism (suspending rendering and showing a fallback) is expected to be stable even in React 16.6. We've used it for code splitting in production for months. However, the higher-level APIs for data fetching are very unstable. React Cache is rapidly changing, and will change at least a few more times. There are some low-level APIs that are [missing](https://github.com/reactjs/rfcs/pull/89) for a good higher-level API to be possible. We don't recommend using React Cache anywhere except very early experiments. Note that React Cache itself isn't strictly tied to React releases, but the current alphas lack basic features as cache invalidation, and you'll run into a wall very soon. We expect to have something usable with this React release. - -Eventually we'd like most data fetching to happen through Suspense but it will take a long time until all integrations are ready. In practice we expect it to be adopted very incrementally, and often through layers like Apollo or Relay rather than directly. Missing higher level APIs aren't the only obstacle — there are also some important UI patterns we don't support yet such as [showing progress indicator outside of the loading view hierarchy](https://github.com/facebook/react/issues/14248). As always, we will communicate our progress in the release notes on this blog. - -**Status in React DOM and React Native:** Technically, a compatible cache would already work with `` in React 16.6. However, we don't expect to have a good cache implementation until this React minor release. If you're feeling adventurous, you can try to write your own cache by looking at the React Cache alphas. However, note that the mental model is sufficiently different that there's a high risk of misunderstanding it until the docs are ready. - -**Status in React DOM Server:** Suspense is not available in the server renderer yet. As we mentioned earlier, we've started work on a new asynchronous server renderer that will support Suspense, but it's a large project and will take a good chunk of 2019 to complete. - -**Recommendation:** Wait for this minor React release in order to use Suspense for data fetching. Don’t try to use Suspense features in 16.6 for it; it’s not supported. However, your existing `` components for code splitting will be able to show loading states for data too when Suspense for Data Fetching becomes officially supported. - -## Other Projects - -### Modernizing React DOM - -We started an investigation into [simplifying and modernizing](https://github.com/facebook/react/issues/13525) ReactDOM, with a goal of reduced bundle size and aligning closer with the browser behavior. It is still early to say which specific bullet points will "make it" because the project is in an exploratory phase. We will communicate our progress on that issue. - -### Suspense for Server Rendering - -We started designing a new server renderer that supports Suspense (including waiting for asynchronous data on the server without double rendering) and progressively loading and hydrating page content in chunks for best user experience. You can watch an overview of its early prototype in [this talk](https://www.youtube.com/watch?v=z-6JC0_cOns). The new server renderer is going to be our major focus in 2019, but it's too early to say anything about its release schedule. Its development, as always, [will happen on GitHub](https://github.com/facebook/react/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+fizz). - ------ - -And that's about it! As you can see, there's a lot here to keep us busy but we expect much progress in the coming months. - -We hope this post gives you an idea of what we're working on, what you can use today, and what you can expect to use in the future. While there's a lot of discussion about new features on social media platforms, you won't miss anything important if you read this blog. - -We're always open to feedback, and love to hear from you in the [RFC repository](https://github.com/reactjs/rfcs), [the issue tracker](https://github.com/facebook/react/issues), and [on Twitter](https://mobile.twitter.com/reactjs). - - - - diff --git a/content/blog/2018-12-19-react-v-16-7.md b/content/blog/2018-12-19-react-v-16-7.md deleted file mode 100644 index 2f66cb743e..0000000000 --- a/content/blog/2018-12-19-react-v-16-7.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "React v16.7: No, This Is Not the One With Hooks" -author: [acdlite] ---- - -Our latest release includes an important performance bugfix for `React.lazy`. Although there are no API changes, we're releasing it as a minor instead of a patch. - -## Why Is This Bugfix a Minor Instead of a Patch? - -React follows [semantic versioning](/docs/faq-versioning.html). Typically, this means that we use patch versions for bugfixes, and minors for new (non-breaking) features. However, we reserve the option to release minor versions even if they do not include new features. The motivation is to reserve patches for changes that have a very low chance of breaking. Patches are the most important type of release because they sometimes contain critical bugfixes. That means patch releases have a higher bar for reliability. It's unacceptable for a patch to introduce additional bugs, because if people come to distrust patches, it compromises our ability to fix critical bugs when they arise — for example, to fix a security vulnerability. - -We never intend to ship bugs. React has a hard-earned reputation for stability, and we intend to keep it that way. We thoroughly test every version of React before releasing. This includes unit tests, generative (fuzzy) tests, integration tests, and internal dogfooding across tens of thousands of components. However, sometimes we make mistakes. That's why, going forward, our policy will be that if a release contains non-trivial changes, we will bump the minor version, even if the external behavior is the same. We'll also bump the minor when changing `unstable_`-prefixed APIs. - -## Can I Use Hooks Yet? - -Not yet, but soon! - -At React Conf, we said that 16.7 would be the first release to include Hooks. This was a mistake. We shouldn't have attached a specific version number to an unreleased feature. We'll avoid this in the future. - -Although 16.7 does not include Hooks, please do not infer anything about the timeline of the Hooks launch. Our plans for Hooks are unchanged: - -- The [Hooks proposal](https://github.com/reactjs/rfcs/pull/68) was accepted ([with minor planned changes in response to feedback](https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884)). -- The [implementation](https://github.com/facebook/react/commit/7bee9fbdd49aa5b9365a94b0ddf6db04bc1bf51c) was merged into the React repo (behind a feature flag). -- We're currently in the testing phase, and you can expect a public release within a few months. - -We've heard from many people who want to start using Hooks in their apps. We also can't wait to ship them! But because Hooks changes how we write React components, we are taking extra time to get the details right. We appreciate your patience as we prepare this exciting new feature for widespread, ahem, *use*. - -Learn more about [our roadmap](/blog/2018/11/27/react-16-roadmap.html) in our previous post. - - -## Installation - -React v16.7.0 is available on the npm registry. - -To install React 16 with Yarn, run: - -```bash -yarn add react@^16.7.0 react-dom@^16.7.0 -``` - -To install React 16 with npm, run: - -```bash -npm install --save react@^16.7.0 react-dom@^16.7.0 -``` - -We also provide UMD builds of React via a CDN: - -```html - - -``` - -Refer to the documentation for [detailed installation instructions](/docs/installation.html). - -## Changelog - -### React DOM - -* Fix performance of `React.lazy` for large numbers of lazily-loaded components. ([@acdlite](http://github.com/acdlite) in [#14429](https://github.com/facebook/react/pull/14429)) -* Clear fields on unmount to avoid memory leaks. ([@trueadm](http://github.com/trueadm) in [#14276](https://github.com/facebook/react/pull/14276)) -* Fix bug with SSR and context when mixing `react-dom/server@16.6` and `react@<16.6`. ([@gaearon](http://github.com/gaearon) in [#14291](https://github.com/facebook/react/pull/14291)) -* Fix a performance regression in profiling mode. ([@bvaughn](http://github.com/bvaughn) in [#14383](https://github.com/facebook/react/pull/14383)) - -### Scheduler (Experimental) - -* Post to MessageChannel instead of window. ([@acdlite](http://github.com/acdlite) in [#14234](https://github.com/facebook/react/pull/14234)) -* Reduce serialization overhead. ([@developit](http://github.com/developit) in [#14249](https://github.com/facebook/react/pull/14249)) -* Fix fallback to `setTimeout` in testing environments. ([@bvaughn](http://github.com/bvaughn) in [#14358](https://github.com/facebook/react/pull/14358)) -* Add methods for debugging. ([@mrkev](http://github.com/mrkev) in [#14053](https://github.com/facebook/react/pull/14053)) diff --git a/content/community/complementary-tools.it-IT.md b/content/community/complementary-tools.it-IT.md old mode 100644 new mode 100755 diff --git a/content/community/complementary-tools.ko-KR.md b/content/community/complementary-tools.ko-KR.md old mode 100644 new mode 100755 diff --git a/content/community/complementary-tools.md b/content/community/complementary-tools.md old mode 100644 new mode 100755 diff --git a/content/community/complementary-tools.zh-CN.md b/content/community/complementary-tools.zh-CN.md old mode 100644 new mode 100755 diff --git a/content/community/conferences.it-IT.md b/content/community/conferences.it-IT.md old mode 100644 new mode 100755 diff --git a/content/community/conferences.ko-KR.md b/content/community/conferences.ko-KR.md old mode 100644 new mode 100755 diff --git a/content/community/conferences.md b/content/community/conferences.md old mode 100644 new mode 100755 index 5591e65b41..fd93bb3997 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -4,73 +4,60 @@ title: Conferences layout: community sectionid: community permalink: community/conferences.html -redirect_from: - - "docs/conferences.html" +redirect_from: "docs/conferences.html" --- -Do you know of a local React.js conference? Add it here! (Please keep the list chronological) - ## Upcoming Conferences -### React Rally -August 16-17 in Salt Lake City, Utah USA - -[Website](http://www.reactrally.com) - [Twitter](https://twitter.com/reactrally) - -### React DEV Conf China -August 18 in Guangzhou, China - -[Website](https://react.w3ctech.com) - -### ReactFoo Delhi -August 18 in Delhi, India +### ReactJS Day 2017 +October 6 in Verona, Italy -[Website](https://reactfoo.in/2018-delhi/) - [Twitter](https://twitter.com/reactfoo) - [Past talks](https://hasgeek.tv) +[Website](http://2017.reactjsday.it) - [Twitter](https://twitter.com/reactjsday) -### Byteconf React 2018 -August 31 streamed online, via Twitch +### React Conf Brasil 2017 +October 7 in Sao Paulo, Brazil -[Website](https://byteconf.com) - [Twitch](https://twitch.tv/byteconf) - [Twitter](https://twitter.com/byteconf) +[Website](http://reactconfbr.com.br) - [Twitter](https://twitter.com/reactconfbr) - [Facebook](https://www.facebook.com/reactconf/) -### React Native EU 2018 -September 5-6 in Wrocław, Poland +### State.js Conference 2017 +October 13 in Stockholm, Sweden -[Website](https://react-native.eu) - [Twitter](https://twitter.com/react_native_eu) - [Facebook](https://www.facebook.com/reactnativeeu) +[Website](https://statejs.com/) -### React Alicante 2018 -September 13-15 in Alicante, Spain +### React Summit 2017 +October 21 in Lagos, Nigeria -[Website](http://reactalicante.es) - [Twitter](https://twitter.com/ReactAlicante) +[Website](https://reactsummit2017.splashthat.com/) - [Twitter](https://twitter.com/DevCircleLagos/) - [Facebook](https://www.facebook.com/groups/DevCLagos/) -### React Boston 2018 -September 29-30 in Boston, Massachusetts USA +### ReactiveConf 2017 +October 25–27, Bratislava, Slovakia -[Website](http://www.reactboston.com/) - [Twitter](https://twitter.com/ReactBoston) +[Website](https://reactiveconf.com) -### ReactJS Day 2018 -October 5 in Verona, Italy +### React Seoul 2017 +November 4 in Seoul, South Korea -[Website](http://2018.reactjsday.it) - [Twitter](https://twitter.com/reactjsday) +[Website](http://seoul.reactjs.kr/en) -### React Conf Brasil 2018 -October 20 in Sao Paulo, Brazil +### React Day Berlin +December 2, Berlin, Germany -[Website](http://reactconfbr.com.br) - [Twitter](https://twitter.com/reactconfbr) - [Facebook](https://www.facebook.com/reactconf) +[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) -### React Conf 2018 -October 25-26 in Henderson, Nevada USA +### AgentConf 2018 +January 25-28 in Dornbirn, Austria -[Website](https://conf.reactjs.org/) +[Website](http://agent.sh/) -### ReactNext 2018 -November 4 in Tel Aviv, Israel +### React Amsterdam 2018 +April 13 in Amsterdam, The Netherlands -[Website](https://react-next.com) - [Twitter](https://twitter.com/ReactNext) - [Facebook](https://facebook.com/ReactNext2016) +[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Facebook](https://www.facebook.com/reactamsterdam) -### React Day Berlin 2018 -November 30, Berlin, Germany +### ReactEurope 2018 +May 17-18 in Paris, France -[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://www.youtube.com/channel/UC1EYHmQYBUJjkmL6OtK4rlw) +[Website](https://www.react-europe.org) - [Twitter](https://twitter.com/ReactEurope) - [Facebook](https://www.facebook.com/ReactEurope) ## Past Conferences @@ -139,17 +126,17 @@ January 20-21 in Dornbirn, Austria ### React Conf 2017 March 13-14 in Santa Clara, CA -[Website](http://conf.reactjs.org/) - [Videos](https://www.youtube.com/watch?v=7HSd1sk07uU&list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0) +[Website](http://conf.reactjs.org/) ### React London 2017 March 28th at the [QEII Centre, London](http://qeiicentre.london/) -[Website](http://react.london/) - [Videos](https://www.youtube.com/watch?v=2j9rSur_mnk&list=PLW6ORi0XZU0CFjdoYeC0f5QReBG-NeNKJ) +[Website](http://react.london/) ### React Amsterdam 2017 April 21st in Amsterdam, The Netherlands -[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Videos](https://www.youtube.com/watch?v=NQyL-Dm7Kig&list=PLNBNS7NRGKMHxfm0CcYNuINLdRw7r4a9M) +[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) ### ReactEurope 2017 May 18th & 19th in Paris, France @@ -159,126 +146,34 @@ May 18th & 19th in Paris, France ### Chain React 2017 July 10-11 in Portland, Oregon USA -[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf) - [Videos](https://www.youtube.com/watch?v=cz5BzwgATpc&list=PLFHvL21g9bk3RxJ1Ut5nR_uTZFVOxu522) +[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf) -### React Rally 2017 +### React Rally August 24-25 in Salt Lake City, Utah USA -[Website](http://www.reactrally.com) - [Twitter](https://twitter.com/reactrally) - [Videos](https://www.youtube.com/watch?v=f4KnHNCZcH4&list=PLUD4kD-wL_zZUhvAIHJjueJDPr6qHvkni) +[Website](http://www.reactrally.com) - [Twitter](https://twitter.com/reactrally) ### React Native EU 2017 September 6-7 in Wroclaw, Poland -[Website](http://react-native.eu/) - [Videos](https://www.youtube.com/watch?v=453oKJAqfy0&list=PLzUKC1ci01h_hkn7_KoFA-Au0DXLAQZR7) +[Website](http://react-native.eu/) ### ReactNext 2017 September 8-10 in Tel Aviv, Israel -[Website](http://react-next.com/) - [Twitter](https://twitter.com/ReactNext) - [Videos (Hall A)](https://www.youtube.com/watch?v=eKXQw5kR86c&list=PLMYVq3z1QxSqq6D7jxVdqttOX7H_Brq8Z), [Videos (Hall B)](https://www.youtube.com/watch?v=1InokWxYGnE&list=PLMYVq3z1QxSqCZmaqgTXLsrcJ8mZmBF7T) +[Website](http://react-next.com/) - [Twitter](https://twitter.com/ReactNext) ### ReactFoo 2017 September 14 in Bangalore, India -[Website](https://reactfoo.in/2017/) - [Videos](https://www.youtube.com/watch?v=3G6tMg29Wnw&list=PL279M8GbNsespKKm1L0NAzYLO6gU5LvfH) +[Website](https://reactfoo.in/2017/) ### React Boston 2017 September 23-24 in Boston, Massachusetts USA -[Website](http://www.reactboston.com/) - [Twitter](https://twitter.com/ReactBoston) - [Videos](https://www.youtube.com/watch?v=2iPE5l3cl_s&list=PL-fCkV3wv4ub8zJMIhmrrLcQqSR5XPlIT) +[Website](http://www.reactboston.com/) - [Twitter](https://twitter.com/ReactBoston) ### React Alicante 2017 September 28-30 in Alicante, Spain -[Website](http://reactalicante.es) - [Twitter](https://twitter.com/ReactAlicante) - [Videos](https://www.youtube.com/watch?v=UMZvRCWo6Dw&list=PLd7nkr8mN0sWvBH_s0foCE6eZTX8BmLUM) - -### ReactJS Day 2017 -October 6 in Verona, Italy - -[Website](http://2017.reactjsday.it) - [Twitter](https://twitter.com/reactjsday) - [Videos](https://www.youtube.com/watch?v=bUqqJPIgjNU&list=PLWK9j6ps_unl293VhhN4RYMCISxye3xH9) - -### React Conf Brasil 2017 -October 7 in Sao Paulo, Brazil - -[Website](http://reactconfbr.com.br) - [Twitter](https://twitter.com/reactconfbr) - [Facebook](https://www.facebook.com/reactconf/) - -### State.js Conference 2017 -October 13 in Stockholm, Sweden - -[Website](https://statejs.com/) - -### React Summit 2017 -October 21 in Lagos, Nigeria - -[Website](https://reactsummit2017.splashthat.com/) - [Twitter](https://twitter.com/DevCircleLagos/) - [Facebook](https://www.facebook.com/groups/DevCLagos/) - -### ReactiveConf 2017 -October 25–27, Bratislava, Slovakia - -[Website](https://reactiveconf.com) - [Videos](https://www.youtube.com/watch?v=BOKxSFB2hOE&list=PLa2ZZ09WYepMB-I7AiDjDYR8TjO8uoNjs) - -### React Seoul 2017 -November 4 in Seoul, South Korea - -[Website](http://seoul.reactjs.kr/en) - -### React Day Berlin 2017 -December 2, Berlin, Germany - -[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://www.youtube.com/watch?v=UnNLJvHKfSY&list=PL-3BrJ5CiIx5GoXci54-VsrO6GwLhSHEK) - -### ReactFoo Pune -January 19-20, Pune, India - -[Website](https://reactfoo.in/2018-pune/) - [Twitter](https://twitter.com/ReactFoo) - -### AgentConf 2018 -January 25-28 in Dornbirn, Austria - -[Website](http://agent.sh/) - -### ReactFest 2018 -March 8-9 in London, UK - -[Website](https://reactfest.uk/) - [Twitter](https://twitter.com/ReactFest) - [Videos](https://www.youtube.com/watch?v=YOCrJ5vRCnw&list=PLRgweB8YtNRt-Sf-A0y446wTJNUaAAmle) - -### Reactathon 2018 -March 20-22 in San Francisco, USA - -[Website](https://www.reactathon.com/) - [Twitter](https://twitter.com/reactathon) - [Videos (fundamentals)](https://www.youtube.com/watch?v=knn364bssQU&list=PLRvKvw42Rc7OWK5s-YGGFSmByDzzgC0HP), [Videos (advanced day1)](https://www.youtube.com/watch?v=57hmk4GvJpk&list=PLRvKvw42Rc7N0QpX2Rc5CdrqGuxzwD_0H), [Videos (advanced day2)](https://www.youtube.com/watch?v=1hvQ8p8q0a0&list=PLRvKvw42Rc7Ne46QAjWNWFo1Jf0mQdnIW) - -### React Native Camp UA 2018 -March 31 in Kiev, Ukraine - -[Website](http://reactnative.com.ua/) - [Twitter](https://twitter.com/reactnativecamp) - [Facebook](https://www.facebook.com/reactnativecamp/) - -### React Amsterdam 2018 -April 13 in Amsterdam, The Netherlands - -[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Facebook](https://www.facebook.com/reactamsterdam) - -### React Finland 2018 -April 24-26 in Helsinki, Finland - -[Website](https://react-finland.fi/) - [Twitter](https://twitter.com/ReactFinland) - -### 2018 -April 28 in Sofia, Bulgaria - -[Website](http://react-not-a-conf.com/) - [Twitter](https://twitter.com/reactnotaconf) - [Facebook](https://www.facebook.com/groups/1614950305478021/) - -### ReactEurope 2018 -May 17-18 in Paris, France - -[Website](https://www.react-europe.org) - [Twitter](https://twitter.com/ReactEurope) - [Facebook](https://www.facebook.com/ReactEurope) - -### ReactFoo Mumbai -May 26 in Mumbai, India - -[Website](https://reactfoo.in/2018-mumbai/) - [Twitter](https://twitter.com/reactfoo) - [Past talks](https://hasgeek.tv) - -### Chain React 2018 -July 11-13 in Portland, Oregon USA - -[Website](https://infinite.red/ChainReactConf) - [Twitter](https://twitter.com/chainreactconf) - -## +[Website](http://reactalicante.es) - [Twitter](https://twitter.com/ReactAlicante) diff --git a/content/community/conferences.zh-CN.md b/content/community/conferences.zh-CN.md old mode 100644 new mode 100755 diff --git a/content/community/courses.md b/content/community/courses.md index 5da83fe511..b0d4fd5254 100644 --- a/content/community/courses.md +++ b/content/community/courses.md @@ -12,15 +12,13 @@ permalink: community/courses.html - [Egghead.io: Start Learning React](https://egghead.io/courses/start-learning-react) - This series will explore the basic fundamentals of React to get you started. -- [React Crash Course 2018](https://www.youtube.com/watch?v=Ke90Tje7VS0) - A beginner-friendly crash course through the most important React topics. - - [React Armory: Learn React by Itself](https://reactarmory.com/guides/learn-react-by-itself) - With React Armory, you can learn React without the buzzwords. - [The Road to Learn React](https://www.robinwieruch.de/the-road-to-learn-react/) - Build a real world application in plain React without complicated tooling. -- [Egghead.io: The Beginner's Guide to ReactJS](https://egghead.io/courses/the-beginner-s-guide-to-reactjs) - Free course for React newbies and those looking to get a better understanding of React fundamentals. +- [React Training: React Patterns](https://reacttraining.com/patterns/) - Free lectures from React Training's "Advanced React.js" course. -- [Free React Bootcamp](https://tylermcginnis.com/free-react-bootcamp/) - Recordings from three days of a free online React bootcamp. +- [Egghead.io: The Beginner's Guide to ReactJS](https://egghead.io/courses/the-beginner-s-guide-to-reactjs) - Free course for React newbies and those looking to get a better understanding of React fundamentals. ## Paid Courses @@ -34,14 +32,6 @@ permalink: community/courses.html - [React for Beginners](https://reactforbeginners.com/) - Learn React in just a couple of afternoons. -- [React for Designers](https://designcode.io/react) - A 6-hour React course for designers, by designers. - -- [React Essentials for Designers](https://learnreact.design) - React courses tailored for designers: the fundamentals, capabilities, limitations and how they relate to design. - -- [Essential React](https://learnreact.com/lessons/2018-essential-react-1-overview) - A crash course for doers, moving fast from "Hello World" to advanced component composition. - - [React Training: Advanced React.js](https://courses.reacttraining.com/p/advanced-react) - Take your React skills to the next level. - [Tyler McGinnis](https://tylermcginnis.com/courses) - Tyler McGinnis provides access to his courses for a monthly fee. Courses include "React Fundamentals" and "Universal React". - -- [Mastering React](https://codewithmosh.com/p/mastering-react/) - Build professional interactive apps with React. diff --git a/content/community/examples.it-IT.md b/content/community/examples.it-IT.md old mode 100644 new mode 100755 diff --git a/content/community/examples.ko-KR.md b/content/community/examples.ko-KR.md old mode 100644 new mode 100755 diff --git a/content/community/examples.md b/content/community/examples.md old mode 100644 new mode 100755 index 09606a27da..bccc3287a4 --- a/content/community/examples.md +++ b/content/community/examples.md @@ -1,23 +1,5 @@ --- -id: examples -title: Example Projects -layout: community -sectionid: community -permalink: community/examples.html +permalink: docs/examples.html +layout: redirect +dest_url: https://github.com/facebook/react/wiki/Examples --- - -There are many example projects created by the React community. Feel free to add your own project. If you add a project, please commit to keeping it up to date with the latest versions of React. - - -* **[Calculator](https://github.com/ahfarmer/calculator)** Implementation of the iOS calculator built in React -* **[Emoji Search](https://github.com/ahfarmer/emoji-search)** Simple React app for searching emoji -* **[Github Battle App](https://github.com/ReactTraining/react-fundamentals/tree/hosting)** Battle two Github users and see the most popular Github projects for any language. -* **[React Powered Hacker News Client](https://github.com/insin/react-hn)** A React & react-router-powered implementation of Hacker News using its Firebase API. -* **[Pokedex](https://github.com/alik0211/pokedex)** The list of Pokémon with live search -* **[Shopping Cart](https://github.com/jeffersonRibeiro/react-shopping-cart)** Simple ecommerce cart application built using React -* **[Progressive Web Tetris](https://github.com/skidding/flatris)** Besides a beautiful, mobile-friendly implementation of Tetris, this project is a playground for integrating and experimenting with web technologies. -* **[Product Comparison Page](https://github.com/Rhymond/product-compare-react)** Simple Product Compare page built in React -* **[Hacker News Clone React/GraphQL](https://github.com/clintonwoo/hackernews-react-graphql)** Hacker News clone rewritten with universal JavaScript, using React and GraphQL. -* **[Bitcoin Price Index](https://github.com/mrkjlchvz/bitcoin-price-index)** Simple bitcoin price index data from CoinDesk API. -* **[Builder Book](https://github.com/builderbook/builderbook)** Open source web app to write and host documentation or sell books. Built with React, Material-UI, Next, Express, Mongoose, MongoDB. -* **[GFonts Space](https://github.com/pankajladhar/GFontsSpace)** A space which allows user to play with Google fonts. Built with React, Redux and React-Router. diff --git a/content/community/examples.zh-CN.md b/content/community/examples.zh-CN.md old mode 100644 new mode 100755 diff --git a/content/community/nav.yml b/content/community/nav.yml old mode 100644 new mode 100755 index 50bab1e5e8..776730fb60 --- a/content/community/nav.yml +++ b/content/community/nav.yml @@ -1,42 +1,14 @@ -- title: 社区资源 +- title: Community Resources items: - id: support - title: 帮助 - - id: courses - title: 课程 - - id: examples - title: 示例 - - id: meetups - title: 线下交流 + title: Where To Get Support - id: conferences - title: 会议 - - id: articles - title: 文章 - - id: podcasts - title: Podcasts + title: Conferences - id: videos - title: 视频 - - id: external-resources - title: 其他 -- title: 工具 - items: - - id: debugging-tools - title: 调试 - - id: component-workbenches - title: 组件开发 - - id: jsx-integrations - title: JSX 集成 - - id: starter-kits - title: 脚手架 - - id: routing - title: 路由 - - id: model-management - title: 模型管理 - - id: data-fetching - title: 数据交互 - - id: testing - title: Testing - - id: ui-components - title: UI 组件 - - id: misc - title: 杂项 + title: Videos + - id: examples + title: Examples + href: https://github.com/facebook/react/wiki/Examples + - id: complementary-tools + title: Complementary Tools + href: https://github.com/facebook/react/wiki/Complementary-Tools diff --git a/content/community/support.md b/content/community/support.md old mode 100644 new mode 100755 index 638f897d0a..5e42f82865 --- a/content/community/support.md +++ b/content/community/support.md @@ -4,31 +4,41 @@ title: Where To Get Support layout: community sectionid: community permalink: community/support.html -redirect_from: - - "support.html" +redirect_from: "support.html" --- -React has a community of millions of developers. - -On this page we've listed some React-related communities that you can be a part of; see the other pages in this section for additional online and in-person learning materials. +**React** is worked on full-time by Facebook's product infrastructure and Instagram's user interface engineering teams. They're often around and available for questions. ## Stack Overflow -Stack Overflow is a popular forum to ask code-level questions or if you're stuck with a specific error. Read through the [existing questions](http://stackoverflow.com/questions/tagged/reactjs) tagged with **reactjs** or [ask your own](http://stackoverflow.com/questions/ask?tags=reactjs)! +Many members of the community use Stack Overflow to ask questions. Read through the [existing questions](http://stackoverflow.com/questions/tagged/reactjs) tagged with **reactjs** or [ask your own](http://stackoverflow.com/questions/ask?tags=reactjs)! + +## Discussion Forum + +For longer-form conversations about React, we've set up a [discussion forum at **discuss.reactjs.org**](https://discuss.reactjs.org/). This forum is a great place for discussion about best practices and application architecture as well as the future of React. If you have an answerable code-level question, please post it to Stack Overflow instead. + +In the forum there's also a category for job posts and a category for discussion of our weekly meeting notes. + +## React Community on Hashnode + +[Hashnode's React node](https://hashnode.com/n/reactjs) is a great place to stay up-to-date with React discussion, news and stories. + +## Reactiflux Chat + +If you need an answer right away, check out the [Reactiflux Discord](https://discord.gg/0ZcbPKXt5bZjGY5n) community. There are usually a number of React experts there who can help out or point you to somewhere you might want to look. -## Popular Discussion Forums +## Freenode IRC -There are many online forums which are a great place for discussion about best practices and application architecture as well as the future of React. If you have an answerable code-level question, Stack Overflow is usually a better fit. +Some developers also hang out in [#reactjs on Freenode](http://irc.lc/freenode/reactjs). -Each community consists of many thousands of React users. +>Note: +> +>Our IRC channel is called **#reactjs**. It is *not* called **#react** or **#reactos**. +> +>The **#reactos** channel belongs to an unrelated [ReactOS](https://reactos.org/) operating system project. The **#react** channel is not affiliated with us either. To discuss the React JavaScript library on its official IRC channel, please make sure that you post in **#reactjs**. -* [DEV's React community](https://dev.to/t/react) -* [Hashnode's React community](https://hashnode.com/n/reactjs) -* [React Discuss](https://discuss.reactjs.org/) -* [Reactiflux online chat](https://discord.gg/0ZcbPKXt5bZjGY5n) -* [Reddit's React community](https://www.reddit.com/r/reactjs/) -* [Spectrum's React community](https://spectrum.chat/react) +## Facebook and Twitter -## News +For the latest news about React, [like us on Facebook](https://facebook.com/react) and [follow **@reactjs** on Twitter](https://twitter.com/reactjs). In addition, you can use the [#reactjs](https://twitter.com/hashtag/reactjs) hashtag to see what others are saying or add to the conversation. -For the latest news about React, [follow **@reactjs** on Twitter](https://twitter.com/reactjs) and the [official React blog](/blog) on this website. +
    diff --git a/content/community/videos.it-IT.md b/content/community/videos.it-IT.md old mode 100644 new mode 100755 diff --git a/content/community/videos.ko-KR.md b/content/community/videos.ko-KR.md old mode 100644 new mode 100755 diff --git a/content/community/videos.md b/content/community/videos.md old mode 100644 new mode 100755 index 55585db32b..42e8dbd7f2 --- a/content/community/videos.md +++ b/content/community/videos.md @@ -4,73 +4,171 @@ title: Videos layout: community sectionid: community permalink: community/videos.html -redirect_from: - - "docs/videos.html" +redirect_from: "docs/videos.html" --- -Videos dedicated to the discussion of React and the React ecosystem. +### Introduction to React -### React.js Conf 2017 +[Tom Occhino](http://tomocchino.com/) and [Jordan Walke](https://github.com/jordwalke) introduce React at Facebook Seattle. -A playlist of videos from React.js Conf 2017. -[フレーム] +[フレーム] -### React.js Conf 2016 +### Introducing React Native -A playlist of videos from React.js Conf 2016. -[フレーム] +[Tom Occhino](https://twitter.com/tomocchino) reviews the past and present of React in 2015, and teases where it's going next. -### React.js Conf 2015 +[フレーム] -A playlist of videos from React.js Conf 2015. -[フレーム] +### Rethinking Web App Development at Facebook + +Delivering reliable, high-performance web experiences at Facebook's scale has required us to challenge some long-held assumptions about software development. Watch this Facebook F8 2014 talk to learn how we abandoned the traditional MVC paradigm in favor of a more functional application architecture. + +[フレーム] ### Secrets of the Virtual DOM -Pete Hunt at Mountain West JavaScript 2014 discusses why a virtual DOM was built for React, how it compares to other systems, and its relevance to the future of browser technologies - (2014 - 0h44m). +[Pete Hunt](http://www.petehunt.net/) at Mountain West JavaScript 2014 discusses why a virtual DOM was built for React, how it compares to other systems, and its relevance to the future of browser technologies. + [フレーム] -### Flux and Server-side Rendering +### Rethinking Best Practices -Pete Hunt discusses flux and server-side rendering in React - (2014 - 0h55m). -[フレーム] +[Pete Hunt](http://www.petehunt.net/)'s talk at JSConf EU 2013 covers three topics: throwing out the notion of templates and building views with JavaScript, "re-rendering" your entire application when your data changes, and a lightweight implementation of the DOM and events. -### Rethinking Web App Development at Facebook +[フレーム] + + +### High performance functional DOM programming + +Tech Talk by [Pete Hunt](http://www.petehunt.net/) at Meteor DevShop 11. + +[フレーム] + + +### Developing User Interfaces With React + +[Steven Luscher](https://github.com/steveluscher) at Super VanJS 2013. + +[フレーム] -Facebook F8 2014 talk to learn how we abandoned the traditional MVC paradigm in favor of a more functional application architecture - (2014 - 0h44m). -[フレーム] ### Introduction to React -Stoyan Stefanov gives an introduction to React at LAWebSpeed meetup - (2014 - 0h51m). +[Stoyan Stefanov](http://www.phpied.com/) at LAWebSpeed meetup. + [フレーム] -### React and Flux: Building Applications with a Unidirectional Data Flow +### Going big with React -Facebook engineers Bill Fisher and Jing Chen talk about Flux and React at Forward JS 2014, and how using an application architecture with a unidirectional data flow cleans up a lot of their code. -[フレーム] +Areeb Malik investigates how React performs in a high stress situation, and how it helped his team build safe code on a massive scale. -### Going Big with React +[![going big with React](https://i.vimeocdn.com/video/481670116_650.jpg)](https://skillsmatter.com/skillscasts/5429-going-big-with-react#video) -Areeb Malik investigates how React performs in a high stress situation, and how it helped his team build safe code on a massive scale - (2014 - 0h31m). -[![going big with React](https://i.vimeocdn.com/video/481670116_650.jpg)] +### Backbone + React + Middleman Screencast +This screencast shows how to integrate Backbone with React using [Backbone-React-Component](https://github.com/magalhas/backbone-react-component). -### Rethinking Best Practices +[フレーム] -Pete Hunt's talk at JSConf EU 2013 covers three topics: throwing out the notion of templates and building views with JavaScript, "re-rendering" your entire application when your data changes, and a lightweight implementation of the DOM and events - (2013 - 0h30m). -[フレーム] +### React, or how to make life simpler -### High Performance Functional DOM Programming -Pete Hunt discusses high performance functional programming with React at Meteor DevShop 11 - (2013 - 0h31m). -[フレーム] +Tech talk by [Alexander Solovyov](http://solovyov.net/) at FrontEnd Dev Conf '14 (Russian). -### Developing User Interfaces With React +[フレーム] -Steven Luscher discusses developing user interfaces at Super VanJS 2013 - (2013 - 0h29m). -[フレーム] -### Introduction to React +### React and Flux: Building Applications with a Unidirectional Data Flow -Tom Occhino and Jordan Walke introduce React at Facebook Seattle - (2013 - 1h20m). -[フレーム] +Facebook engineers [Bill Fisher](https://twitter.com/fisherwebdev) and [Jing Chen](https://twitter.com/jingc) talk about Flux and React at Forward JS 2014, and how using an application architecture with a unidirectional data flow cleans up a lot of their code. + +[フレーム] + +> [Slides and sample code](https://github.com/zertosh/ssr-demo-kit) + +### CodeWinds Podcast + +[Pete Hunt](http://www.petehunt.net/) talked with [Jeff Barczewski](http://jeff.barczewski.com/) about React in [CodeWinds Episode 4](http://codewinds.com/podcast/004.html). +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    02:08What is React and why use it?27:17Rendering HTML on the server with Node.js. Rendering backends
    03:08The symbiotic relationship of ClojureScript and React29:20React evolved through survival of the fittest at Facebook
    04:54The history of React and why it was created30:15Ideas for having state on server and client, using web sockets.
    09:43Updating web page with React without using data binding32:05React-multiuser - distributed shared mutable state using Firebase
    13:11Using the virtual DOM to change the browser DOM33:03Better debugging with React using the state transitions, replaying events
    13:57Programming with React, render targets HTML, canvas, other34:08Differences from Web Components
    16:45Working with designers. Contrasted with Ember and AngularJS34:25Notable companies using React
    21:45JSX Compiler bridging HTML and React javascript35:16Could a React backend plugin be created to target PDF?
    23:50Autobuilding JSX and in browser tools for React36:30Future of React, what's next?
    24:50Tips and tricks to working with React, getting started39:38Contributing and getting help
    + +### JavaScript Jabber Podcast + +[Pete Hunt](http://www.petehunt.net/) and [Jordan Walke](https://github.com/jordwalke) talked about React in [JavaScript Jabber 73](https://devchat.tv/js-jabber/073-jsj-react-with-pete-hunt-and-jordan-walke). +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    01:34Pete Hunt Introduction23:06Supporting Node.js
    02:45Jordan Walke Introduction24:03rendr
    04:15React26:02JSX
    06:3860 Frames Per Second30:31requestAnimationFrame
    09:34Data Binding34:15React and Applications
    12:31Performance38:12React Users Khan Academy
    17:39Diffing Algorithm39:53Making it work
    19:36DOM Manipulation
    diff --git a/content/community/videos.zh-CN.md b/content/community/videos.zh-CN.md old mode 100644 new mode 100755 diff --git a/content/docs/accessibility.md b/content/docs/accessibility.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-animation.md b/content/docs/addons-animation.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-create-fragment.md b/content/docs/addons-create-fragment.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-perf.md b/content/docs/addons-perf.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-pure-render-mixin.md b/content/docs/addons-pure-render-mixin.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-shallow-compare.md b/content/docs/addons-shallow-compare.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-shallow-renderer.md b/content/docs/addons-shallow-renderer.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-test-utils.md b/content/docs/addons-test-utils.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-two-way-binding-helpers.md b/content/docs/addons-two-way-binding-helpers.md old mode 100644 new mode 100755 diff --git a/content/docs/addons-update.md b/content/docs/addons-update.md old mode 100644 new mode 100755 diff --git a/content/docs/addons.md b/content/docs/addons.md old mode 100644 new mode 100755 diff --git a/content/docs/cdn-links.md b/content/docs/cdn-links.md index 5be1ff52fe..9205e72121 100644 --- a/content/docs/cdn-links.md +++ b/content/docs/cdn-links.md @@ -6,32 +6,32 @@ prev: add-react-to-an-existing-app.html next: hello-world.html --- -可以通过 CDN 获得 React 和 ReactDOM 的 UMD 版本。 +The UMD builds of React and ReactDOM are available over a CDN. ```html ``` -上述版本仅用于开发环境,不适合用于生产环境。React 的压缩和优化之后的生产环境版本链接如下: +The versions above are only meant for development, and are not suitable for production. Minified and optimized production versions of React are available at: ```html ``` -如果需要加载指定版本的 `react` 和 `react-dom`,可以把 `16` 替换成需要加载的版本号。 +To load a specific version of `react` and `react-dom`, replace `16` with the version number. -### 为什么要使用 `crossorigin` 属性? +### Why the `crossorigin` Attribute? -如果你通过 CDN 的方式引入 React, 我们建议你设置 [`crossorigin`](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) 属性: +If you serve React from a CDN, we recommend to keep the [`crossorigin`](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) attribute set: ```html ``` -我们同时建议你设置 `Access-Control-Allow-Origin: *` HTTP请求头来验证 CDN: +We also recommend to verify that the CDN you are using sets the `Access-Control-Allow-Origin: *` HTTP header: ![Access-Control-Allow-Origin: *](../images/docs/cdn-cors-header.png) -这样可以在 React 的16及以上的版本中有更好的 [错误处理体验](/blog/2017/07/26/error-handling-in-react-16.html)。 +This enables a better [error handling experience](/blog/2017/07/26/error-handling-in-react-16.html) in React 16 and later. diff --git a/content/docs/codebase-overview.md b/content/docs/codebase-overview.md old mode 100644 new mode 100755 diff --git a/content/docs/components-and-props.md b/content/docs/components-and-props.md old mode 100644 new mode 100755 index 11f3a20b7a..4113351a00 --- a/content/docs/components-and-props.md +++ b/content/docs/components-and-props.md @@ -16,7 +16,7 @@ prev: rendering-elements.html next: state-and-lifecycle.html --- -组件可以将UI切分成一些独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。 +组件可以将UI切分成一些的独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。 组件从概念上看就像是函数,它可以接收任意的输入值(称之为"props"),并返回一个需要在页面上展示的React元素。 diff --git a/content/docs/composition-vs-inheritance.md b/content/docs/composition-vs-inheritance.md old mode 100644 new mode 100755 index c0be7c7299..36a84b65ce --- a/content/docs/composition-vs-inheritance.md +++ b/content/docs/composition-vs-inheritance.md @@ -9,7 +9,7 @@ next: thinking-in-react.html React 具有强大的组合模型,我们建议使用组合而不是继承来复用组件之间的代码。 -在本节中,我们将围绕几个 React 新手经常使用继承解决的问题,我们将展示如何用组合来解决它们。 +在本节中,我们将围绕几个 React 新手经常使用继承解决的问题,我们将展示如果用组合来解决它们。 ## 包含关系 diff --git a/content/docs/conditional-rendering.md b/content/docs/conditional-rendering.md old mode 100644 new mode 100755 index 2c8e1f6065..f47721e79c --- a/content/docs/conditional-rendering.md +++ b/content/docs/conditional-rendering.md @@ -120,8 +120,7 @@ ReactDOM.render( 声明变量并使用 `if` 语句是条件渲染组件的不错的方式,但有时你也想使用更简洁的语法,在 JSX 中有如下几种方法。 ### 与运算符 && - -你可以通过使用花括号包裹代码,[在 JSX 中嵌入任何表达式](/docs/introducing-jsx.html#在JSX中使用表达式) ,包括 JavaScript 的逻辑与 && 操作符,它可以方便地实现对一个元素的条件渲染。 +你可以通过用花括号包裹代码[在 JSX 中嵌入任何表达式](/docs/introducing-jsx.html#在JSX中使用表达式) ,也包括 JavaScript 的逻辑与 &&,它可以方便地条件渲染一个元素。 ```js{6-10} function Mailbox(props) { diff --git a/content/docs/context.md b/content/docs/context.md index 51692fcfbf..10b8e1a183 100644 --- a/content/docs/context.md +++ b/content/docs/context.md @@ -77,7 +77,7 @@ React 组件允许 Consumers 订阅 context 的改变。 > > 关于此案例的更多信息, 请看 [render props](/docs/render-props.html). -每当Provider的值发生改变时, 作为Provider后代的所有Consumers都会重新渲染。 从Provider到其后代的Consumers传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新时,后代Consumer也会被更新。 +每当Provider的值发送改变时, 作为Provider后代的所有Consumers都会重新渲染。 从Provider到其后代的Consumers传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新时,后代Consumer也会被更新。 通过使用与[Object.is](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description)相同的算法比较新值和旧值来确定变化。 @@ -119,7 +119,7 @@ React 组件允许 Consumers 订阅 context 的改变。 `embed:context/multiple-contexts.js` -如果两个或者多个上下文的值经常被一起使用,你可能需要考虑创建一个可以同时提供这些值的 render prop 组件 +如果两个或者多个上下文的值经常被一起使用,也许你需要考虑你自己渲染属性的组件提供给它们。 ### 在生命周期方法中访问 Context diff --git a/content/docs/create-a-new-react-app.md b/content/docs/create-a-new-react-app.md deleted file mode 100644 index 4d692f76f8..0000000000 --- a/content/docs/create-a-new-react-app.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: create-a-new-react-app -title: Create a New React App -permalink: docs/create-a-new-react-app.html -redirect_from: - - "docs/add-react-to-a-new-app.html" -prev: add-react-to-a-website.html -next: cdn-links.html ---- - -Use an integrated toolchain for the best user and developer experience. - -This page describes a few popular React toolchains which help with tasks like: - -* Scaling to many files and components. -* Using third-party libraries from npm. -* Detecting common mistakes early. -* Live-editing CSS and JS in development. -* Optimizing the output for production. - -The toolchains recommended on this page **don't require configuration to get started**. - -## You Might Not Need a Toolchain - -If you don't experience the problems described above or don't feel comfortable using JavaScript tools yet, consider [adding React as a plain `>` tag on an HTML page](/docs/add-react-to-a-website.html), optionally [with JSX](/docs/add-react-to-a-website.html#optional-try-react-with-jsx). - -This is also **the easiest way to integrate React into an existing website.** You can always add a larger toolchain if you find it helpful! - -## Recommended Toolchains - -The React team primarily recommends these solutions: - -- If you're **learning React** or **creating a new [single-page](/docs/glossary.html#single-page-application) app,** use [Create React App](#create-react-app). -- If you're building a **server-rendered website with Node.js,** try [Next.js](#nextjs). -- If you're building a **static content-oriented website,** try [Gatsby](#gatsby). -- If you're building a **component library** or **integrating with an existing codebase**, try [More Flexible Toolchains](#more-flexible-toolchains). - -### Create React App - -[Create React App](http://github.com/facebookincubator/create-react-app) is a comfortable environment for **learning React**, and is the best way to start building **a new [single-page](/docs/glossary.html#single-page-application) application** in React. - -It sets up your development environment so that you can use the latest JavaScript features, provides a nice developer experience, and optimizes your app for production. You’ll need to have Node>= 6 and npm>= 5.2 on your machine. To create a project, run: - -```bash -npx create-react-app my-app -cd my-app -npm start -``` - ->Note -> ->`npx` on the first line is not a typo -- it's a [package runner tool that comes with npm 5.2+](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b). - -Create React App doesn't handle backend logic or databases; it just creates a frontend build pipeline, so you can use it with any backend you want. Under the hood, it uses [Babel](http://babeljs.io/) and [webpack](https://webpack.js.org/), but you don't need to know anything about them. - -When you're ready to deploy to production, running `npm run build` will create an optimized build of your app in the `build` folder. You can learn more about Create React App [from its README](https://github.com/facebookincubator/create-react-app#create-react-app-) and the [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#table-of-contents). - -### Next.js - -[Next.js](https://nextjs.org/) is a popular and lightweight framework for **static and server‐rendered applications** built with React. It includes **styling and routing solutions** out of the box, and assumes that you're using [Node.js](https://nodejs.org/) as the server environment. - -Learn Next.js from [its official guide](https://nextjs.org/learn/). - -### Gatsby - -[Gatsby](https://www.gatsbyjs.org/) is the best way to create **static websites** with React. It lets you use React components, but outputs pre-rendered HTML and CSS to guarantee the fastest load time. - -Learn Gatsby from [its official guide](https://www.gatsbyjs.org/docs/) and a [gallery of starter kits](https://www.gatsbyjs.org/docs/gatsby-starters/). - -### More Flexible Toolchains - -The following toolchains offer more flexiblity and choice. We recommend them to more experienced users: - -- **[Neutrino](https://neutrinojs.org/)** combines the power of [webpack](https://webpack.js.org/) with the simplicity of presets, and includes a preset for [React apps](https://neutrinojs.org/packages/react/) and [React components](https://neutrinojs.org/packages/react-components/). - -- **[nwb](https://github.com/insin/nwb)** is particularly great for [publishing React components for npm](https://github.com/insin/nwb/blob/master/docs/guides/ReactComponents.md#developing-react-components-and-libraries-with-nwb). It [can be used](https://github.com/insin/nwb/blob/master/docs/guides/ReactApps.md#developing-react-apps-with-nwb) for creating React apps, too. - -- **[Parcel](https://parceljs.org/)** is a fast, zero configuration web application bundler that [works with React](https://parceljs.org/recipes.html#react). - -- **[Razzle](https://github.com/jaredpalmer/razzle)** is a server-rendering framework that doesn't require any configuration, but offers more flexibility than Next.js. - -## Creating a Toolchain from Scratch - -A JavaScript build toolchain typically consists of: - -* A **package manager**, such as [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/). It lets you take advantage of a vast ecosystem of third-party packages, and easily install or update them. - -* A **bundler**, such as [webpack](https://webpack.js.org/) or [Parcel](https://parceljs.org/). It lets you write modular code and bundle it together into small packages to optimize load time. - -* A **compiler** such as [Babel](http://babeljs.io/). It lets you write modern JavaScript code that still works in older browsers. - -If you prefer to set up your own JavaScript toolchain from scratch, [check out this guide](https://blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658) that re-creates some of the Create React App functionality. - -Don't forget to ensure your custom toolchain [is correctly set up for production](/docs/optimizing-performance.html#use-the-production-build). diff --git a/content/docs/cross-origin-errors.md b/content/docs/cross-origin-errors.md old mode 100644 new mode 100755 diff --git a/content/docs/design-principles.md b/content/docs/design-principles.md old mode 100644 new mode 100755 diff --git a/content/docs/error-boundaries.md b/content/docs/error-boundaries.md old mode 100644 new mode 100755 index 0b6886c5bb..a9cf406faf --- a/content/docs/error-boundaries.md +++ b/content/docs/error-boundaries.md @@ -11,31 +11,29 @@ permalink: docs/error-boundaries.html 部分 UI 的异常不应该破坏了整个应用。为了解决 React 用户的这一问题,React 16 引入了一种称为 "错误边界" 的新概念。 -错误边界是**用于捕获其子组件树 JavaScript 异常,记录错误并展示一个回退的 UI** 的 React 组件,而不是整个组件树的异常。错误边界在渲染期间、生命周期方法内、以及整个组件树构造函数内捕获错误。 +错误边界是**用于捕获其子组件树 JavaScript 异常,记录错误并展示一个回退的 UI** 的 React 组件,而不是整个组件树的异常。错误组件在渲染期间,生命周期方法内,以及整个组件树构造函数内捕获错误。 + +> 注意 -> **注意** -> > 错误边界**无法**捕获如下错误: + > * 事件处理 ([了解更多](https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers)) > * 异步代码 (例如 `setTimeout` 或 `requestAnimationFrame` 回调函数) > * 服务端渲染 > * 错误边界自身抛出来的错误 (而不是其子组件) -一个类组件变成一个错误边界。如果它定义了生命周期方法 [`static getDerivedStateFromError()`](https://reactjs.org/docs/react-component.html#static-getderivedstatefromerror)或者[`componentDidCatch()`](https://reactjs.org/docs/react-component.html#componentdidcatch)中的任意一个或两个。当一个错误被扔出后,使用`static getDerivedStateFromError()`渲染一个退路UI。使用`componentDidCatch()`去记录错误信息。 +如果一个类组件定义了一个名为 `componentDidCatch(error, info):` 的新方法,则其成为一个错误边界: -```js{6-14,17-20} +```js{7-12,15-18} class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } - static getDerivedStateFromError(error) { - // Update state so the next render will show the fallback UI. - return { hasError: true }; - } - componentDidCatch(error, info) { + // Display fallback UI + this.setState({ hasError: true }); // You can also log the error to an error reporting service logErrorToMyService(error, info); } @@ -45,8 +43,7 @@ class ErrorBoundary extends React.Component { // You can render any custom fallback UI return

    Something went wrong.

    ; } - - return this.props.children; + return this.props.children; } } ``` @@ -59,24 +56,46 @@ class ErrorBoundary extends React.Component { ``` -错误边界工作机制类似于JavaScript `catch {}`,只是应用于组件。仅有类组件可以成为错误边界。实践中,大多数时间,你希望定义一个错误边界组件一次并将它贯穿你的整个应用。 +`componentDidCatch()` 方法机制类似于 JavaScript `catch {}`,但是针对组件。仅有类组件可以成为错误边界。实际上,大多数时间你仅想要定义一个错误边界组件并在你的整个应用中使用。 + +注意**错误边界仅可以捕获其子组件的错误**。错误边界无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会向上冒泡至最接近的错误边界。这也类似于 JavaScript 中 catch {} 的工作机制。 + +### componentDidCatch 参数 + +`error` 是被抛出的错误。 -注意**错误边界仅可以捕获组件在树中比他低的组件的错误**。错误边界无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会向上冒泡至最接近的错误边界。这也类似于 JavaScript 中 `catch {}` 的工作机制。 +`info` 是一个含有 `componentStack` 属性的对象。这一属性包含了错误期间关于组件的堆栈信息。 + +```js +//... +componentDidCatch(error, info) { + + /* Example stack information: + in ComponentThatThrows (created by App) + in ErrorBoundary (created by App) + in div (created by App) + in App + */ + logComponentStackToMyService(info.componentStack); +} + +//... +``` ## 在线演示 -检出[this example of declaring and using an error boundary](https://codepen.io/gaearon/pen/wqvxGa?editors=0010) 使用[React 16](https://reactjs.org/blog/2017/09/26/react-v16.0.html). +查看通过 [React 16 beta 版本](https://github.com/facebook/react/issues/10294)来[定义和使用错误边界的例子](https://codepen.io/gaearon/pen/wqvxGa?editors=0010)。 -## 错误边界放到哪里 +## 如何放置错误边界 -错误边界的粒度是由你决定。你可以将其包装在最顶层的路由组件显示给用户"有东西出错"消息,就像服务端框架经常处理崩溃一样。你也可以将单独的插件包装在错误边界内以保护应用其他部分不崩溃。 +错误边界的粒度完全取决于你的应用。你可以将其包装在最顶层的路由组件并为用户展示一个 "发生异常(Something went wrong)"的错误信息,就像服务端框架通常处理崩溃一样。你也可以将单独的插件包装在错误边界内部以保护应用不受该组件崩溃的影响。 -## 未捕获错误的新行为 +## 未捕获错误(Uncaught Errors)的新行为 -这个改变有一个重要的暗示。**从React 16起,任何未被错误边界捕获的错误将导致卸载整个 React 组件树。** +这一改变有非常重要的意义。**自 React 16 开始,任何未被错误边界捕获的错误将会卸载整个 React 组件树。** -我们对这一决定饱含争论,但在我们的经验中放置下一个腐败的UI比完全移除它要更糟糕。例如,在类似 Messenger 的产品中留下一个异常的可见 UI 可能会导致用户将信息发错给别人。类似的,对于支付类的应用来说,什么都不展示也比显示一堆错误更好。 +我们对这一决定饱含争论,但在我们的经验中放置下一个错误的UI比完全移除它要更糟糕。例如,在类似 Messenger 的产品中留下一个异常的可见 UI 可能会导致用户将信息发错给别人。类似的,对于支付类的应用来说,什么都不展示也比显示一堆错误更好。 这一改变意味着随着你迁入到 React 16,你将可能会发现一些已存在你应用中但未曾注意到的崩溃。增加错误边界能够让你在发生异常时提供更好的用户体验。 @@ -91,19 +110,16 @@ React 16 会将渲染期间所有在开发环境下的发生的错误打印到 Error caught by Error Boundary component -你也可以在组件追踪堆栈中查看文件名和行号。这一功能在 [Create React App 项目](https://github.com/facebookincubator/create-react-app)中默认开启: +你也可以在组件堆栈中查看文件名和行数。这一功能在 [Create React App 项目](https://github.com/facebookincubator/create-react-app)中默认开启: Error caught by Error Boundary component with line numbers -若你不使用 Create React App,你可以手动添加该[插件](https://www.npmjs.com/package/babel-plugin-transform-react-jsx-source)到你的 Babel 配置中。注意其仅能在开发环境中使用并且**在生产环境中必须关闭**。 +若你不使用 Create React App,你可以手动添加该[插件](https://www.npmjs.com/package/babel-plugin-transform-react-jsx-source)到你的 Babel 配置中。注意其仅能在开发环境中使用并**禁止在生产环境中使用**。 -> 注意 -> -> 组件名称在栈追踪中的显示依赖于[`Function.name`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name)属性。 If you support older browsers and devices which may not yet provide this natively (e.g. IE 11), consider including a `Function.name` polyfill in your bundled application, such as [`function.name-polyfill`](https://github.com/JamesMGreene/Function.name). 另一种方法, 你可以明确地在所有组件上设置[`displayName`](https://reactjs.org/docs/react-component.html#displayname)属性。 -## 关于try/catch +## 为何不使用 try/catch? -`try` / `catch` 非常棒,但其仅能用在命令式代码下: +`try` / `catch` 非常棒,但其仅能在命令式代码(imperative code)下可用: ```js try { @@ -113,31 +129,30 @@ try { } ``` -然而,React 组件是声明式的并且具体指出什么需要被渲染: +然而,React 组件是声明式的并且具体指出 *声明* 什么需要被渲染: ```js - - ); -} -``` - -`useState`这个方法是我们接触到的第一个"hook"。我们用它完成了一个最简单的组件,接下来我们会看到更多有趣的应用。 - -**你可以立即跳到[下一页](/docs/hooks-overview.html)开始学习Hooks。** 在这一页,我们将继续解释为什么我们要在React中引入Hooks,以及它们将如何帮助你写出超棒的React应用。 - -## 视频介绍 - -在React Conf 2018,Sophie Alpert 和 Dan Abramov介绍了Hooks,然后Ryan Florence演示了如何用它们重构我们的应用。你可以在这里看到这个视频: - -
    - -[フレーム] - -## No Breaking Changes - -在我们继续学习之前,你需要注意: - -* **完全可选** 如果你喜欢Hooks,你可以立即在一些组件和已经存在的代码中使用它们。不过如果你不喜欢也不要紧,你完全没必要学习或者使用它们。 -* **100% 向后兼容** Hooks不包含任何爆炸性的更新。 -* **立即可用** Hooks现在已经包含在alpha版本中。而且我们期望在接受社区反馈后把他们加入到React 16.7版本中。 - -**classes不会被移除** 你可以在这一页的[最后一节](#gradual-adoption-strategy)读到更多关于Hooks的渐进策略。 - -**Hooks不会影响你对React的理解** 恰恰相反,Hooks为React的这些概念提供了更直接的API。之后你将会看到,有了Hooks,你可以以一种更加强大的方式将props, state, context, refs 和生命周期整合起来。 - -**如果你只是想要学学Hooks如何使用,你可以直接跳到[下一页](/docs/hooks-overview.html)。** 当然你也可以继续读这一页。你将会在这里了解到更多我们引入Hooks的原因,以及要如何在已有的代码上使用Hooks重构我们的应用。 - -## 动机 - -Hooks解决了我们在React发布至今的五年来遇到的一系列看似不相关的问题。不论你是刚刚开始学习React,或是一直在用它,甚至你只是在使用与React具有相似组件模型的框架,你一定或多或少注意到这些问题。 - -### 跨组件复用stateful logic(包含状态的逻辑)十分困难 - -React没有提供一种将可复用的行为"attach"到组件上的方式(比如redux的connect方法)。如果你已经使用了一段时间的React,你可能对[render props](/docs/render-props.html) 和 [高阶组件](/docs/higher-order-components.html)有一定的了解,它们的出现就是为了解决逻辑复用的问题。但是这些模式都要求你重新构造你的组件,这可能会非常麻烦。在很多典型的React组件中,你可以在React DevTool里看到我们的组件被层层叠叠的providers, consumers, 高阶组件, render props, 和其他抽象层包裹。当然你可以通过[筛选功能](https://github.com/facebook/react-devtools/pull/503)把它们全部都过滤掉,但是这种现象也指出了一些更深层次的问题:React需要一些更好的底层元素来复用stateful logic. - -使用Hooks,你可以在将含有state的逻辑从组件中抽象出来,这将可以让这些逻辑容易被测试。同时,**Hooks可以帮助你在不重写组件结构的情况下复用这些逻辑。** 这样这些逻辑就可以跨组件复用,甚至你可以将他们分享到社区中。 - -我们将在[自定义Hooks](/docs/hooks-custom.html)中继续这一部分的讨论。 - -### 复杂的组件难以理解 - -我们在刚开始构建我们的组件时它们往往很简单,然而随着开发的进展它们会变得越来越大、越来越混乱,各种逻辑在组件中散落的到处都是。每个生命周期钩子中都包含了一堆互不相关的逻辑。比如我们常常在`componentDidMount` 和 `componentDidUpdate` 中拉取数据,同时`compnentDidMount` 方法可能又包含一些不相干的逻辑,比如设置事件监听(之后需要在 `componentWillUnmount` 中清除)。最终的结果是强相关的代码被分离,反而是不相关的代码被组合在了一起。这显然会导致大量错误。 - -在许多情况下,我们也不太可能将这些组件分解成更小的组件,因为stateful logic到处都是。测试它们也很困难。这是许多人喜欢将React与单独的状态管理库结合使用的原因之一。然而,这通常会引入太多的抽象,需要在不同的文件之间跳转,并且使得重用组件更加困难。 - -为了解决这个问题,**Hooks允许您根据相关部分(例如设置订阅或获取数据)将一个组件分割成更小的函数**,而不是强制基于生命周期方法进行分割。您还可以选择使用一个reducer来管理组件的本地状态,以使其更加可预测。 - -我们将在[使用Effect Hook](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns)中继续这一部分的讨论。 - -### 不止是用户,机器也对Classes难以理解 - -据我们观察,classes是学习React的最大障碍。您必须了解`this`如何在JavaScript中工作,这与它在大多数语言中的工作方式非常不同。必须记住绑定事件处理程序。没有稳定的[语法提案](https://babeljs.io/docs/en/babel-plugin-transform-class-properties/),代码非常冗长。尽管人们可以很好地理解props、state和自顶向下的数据流,但仍然要与类做斗争。React中功能和类组件的区别以及何时使用每种组件都会导致有经验的React开发人员之间的分歧。 - -除此以外,React已经发布了五年,我们还想在未来的五年让他保持稳定。就像在[Svelte](https://svelte.technology/), [Angular](https://angular.io/), [Glimmer](https://glimmerjs.com/)和其他框架中展示的那样,组件的提前编译潜力巨大。尤其是在它不局限于模板的时候。最近我们在测试使用[Prepack](https://prepack.io/)来进行[component folding](https://github.com/facebook/react/issues/7323),而且我们已经初步看到了成果。然而我们发现class组件可能会导致一些让我们做的这些优化白费的编码模式。类也为今天的工具带来了不少的issue。比如,classes不能很好的被minify,同时他们也造成了太多不必要的组件更新。我们想要提供一种便于优化的API。 - -为了解决这些问题,**Hooks让你可以在classes之外使用更多React的新特性。** 从概念上讲,React组件也是更接近于函数的。Hooks基于函数,但是并不会修改React的基本概念。Hooks在不需要您学习复杂的函数式编程的情况下,为您提供了逃离这些问题的途径。 - ->Examples -> ->您可以从[Hooks概览](/docs/hooks-overview.html)开始,快速地学习Hooks。 - -## 渐进策略 - ->**太长不看版: 我们完全没有把classes从React中移除的打算。** - -我们知道React开发者都非常忙。你们可能没有时间去研究我们一个发布的新API。Hooks还非常新,也许你可以等待出现了更多关于它们的示例和教程之后再来学习。 - -我们也理解添加新的底层API的门槛非常的高。对于感到好奇的读者,我们准备了一份[详细的RFC](https://github.com/reactjs/rfcs/pull/68)来提供更多我们设计Hook的细节和动机,我们设计Hooks时的独特视角,以及更多细节。 - -**最重要的是,Hooks与现有的代码可以同时工作,所以你完全可以逐步采用它们。** 我们正在分享这个API,以便得到那些对React的未来感兴趣的人们的反馈——我们将在开放的基础上开发Hooks。 - -最后,您没有必要着急迁移到Hooks。我们建议避免任何"大范围重构",尤其是对已有的、复杂的class组件。"Thinking in Hooks"需要您进行一些思想上的切换。在我们的经验中,最佳实践是先在新的、非关键性的代码中试用Hooks,并且保证团队里的所有人都喜欢它们。在你试用过Hooks之后,请一定要来[这里](https://github.com/facebook/react/issues/new)给我们提供建议或是意见,我们都非常欢迎。 - -我们打算用钩子(Hook)覆盖类的所有现有用例,但是在可预见的将来,我们将继续支持类组件。**在Facebook,我们有成千上万的组件被写成类,我们绝对没有重写它们的计划。相反,我们开始在新代码中与类一起使用钩子(Hook)。** - -## 下一步 - -在这一页的结尾,你应该对Hooks解决了什么样的问题有了一个初步的了解,但是许多细节你可能还不那么清楚。不过不要担心!**让我们去到[下一页](/docs/hooks-overview.html)。在那里我们将会学到更多关于Hooks的例子。** diff --git a/content/docs/hooks-overview.md b/content/docs/hooks-overview.md deleted file mode 100644 index 04fe2ed9a2..0000000000 --- a/content/docs/hooks-overview.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -id: hooks-overview -title: Hooks at a Glance -permalink: docs/hooks-overview.html -next: hooks-state.html -prev: hooks-intro.html ---- - -*Hooks*是React v16.7.0-alpha中加入的新特性。它可以让你在class以外使用state和其他React特性。你可以在[这里](https://github.com/reactjs/rfcs/pull/68)看到关于它的一些讨论。 - -Hooks[向后兼容](/docs/hooks-intro.html#no-breaking-changes)。这个页面为有经验的React用户提供了Hooks的概览。 - -这是一个快节奏的概览。当你感到困惑时,请搜寻下面这样的黄色盒子: - ->详细解释 -> ->阅读[动机](/docs/hooks-intro.html#motivation)以了解我们为什么要在React中引入Hooks。 - -**↑↑↑ 每一部分的结尾都会有一个这样的黄色盒子** 它们链接到详细的解释。 - -## 📌 状态钩子(State Hook) - -这个例子渲染了一个计数器。当你点击按钮时,页面中的值会随之增加: - -```js{1,4,5} -import { useState } from 'react'; - -function Example() { - // 声明一个名为"count"的新状态变量 - const [count, setCount] = useState(0); - - return ( -
    -

    你点击了{count}次

    - -
    - ); -} -``` - -在这里, `useState`是一个*钩子(Hook)* (稍后我们将会谈及它的含义)。我们在一个函数式组件中调用它,为这个组件增加一些内部的状态。React将会在下一次渲染前保存此状态。 `useState`返回一对值:*当前*的状态(state value)和一个可以更新状态的函数。你可以在事件处理程序(event handler)中或其他地方调用这个函数。 它与类组件中的`this.setState`类似,但不能将新旧状态进行合并。(我们在[使用状态钩子](/docs/hooks-state.html)中展示了一个将`useState`和`this.state`进行对比的例子。) - -`useState`唯一的参数就是初始状态(initial state)。在上面的例子中,因为我们的计数器从零开始所以它是`0`。这里的状态与`this.state`不同,它不必是一个对象-- 如果你想这么做,当然也可以。初始状态参数只在第一次渲染中被使用。 - -#### 声明多个状态变量 - -你可以在一个组件中多次使用状态钩子: - -```js -function ExampleWithManyStates() { - // 声明多个状态变量! - const [age, setAge] = useState(42); - const [fruit, setFruit] = useState('banana'); - const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]); - // ... -} -``` - -通过调用`useState`我们声明了一些状态变量,我们可以使用[数组解构](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring)语法赋予这些状态变量不同的名字。这些名字不是`useState` API的一部分。 相反,当你多次调用`useState`时,React假定你在每一次渲染中以相同的顺序调用它们。我们会在之后再来解释为什么这样可以运行以及在什么时候起作用。 - -#### 但是什么是钩子(Hook)? - -钩子是可以让你与React状态以及函数式组件的生命周期特性"挂钩"的函数。钩子是为了让你抛弃类使用React的,所以它不能在类中运行。(我们[不推荐](/docs/hooks-intro.html#gradual-adoption-strategy)你立即重写已经存在的组件,但是如果你喜欢的话可以在新的组件中开始使用钩子。) - -React提供了少量内置的钩子,如`useState`。你也可以创建自己的钩子在不同的组件之间复用有状态的行为。我们先来看一下内置的钩子。 - ->详细解释 -> ->你可以在这个页面上了解到更多关于状态钩子的信息: [使用状态钩子](/docs/hooks-state.html)。 - -## ⚡️ 副作用钩子(Effect Hook) - -你可能之前已经在React中执行过获取数据,订阅或者手动改变DOM。我们称这些操作为"副作用(side effects)"(或者简称为"作用(effects)"),因为它们可以影响其他的组件并且不能在渲染中完成。 - -副作用钩子, `useEffect`, 为函数式组件带来执行副作用的能力。它与类组件中的`componentDidMount` ,`componentDidUpdate`和 `componentWillUnmount`具有相同的用途,但是被统一为一个API。(我们在[使用副作用钩子](/docs/hooks-effect.html)中展示了一个将`useEffect`和这些方法进行对比的例子。) - -举个例子,这个组件在React更新DOM之后设置文档的标题: - -```js{1,6-10} -import { useState, useEffect } from 'react'; - -function Example() { - const [count, setCount] = useState(0); - - // 类似于 componentDidMount 和 componentDidUpdate: - useEffect(() => { - // 使用浏览器API更新文档标题 - document.title = `You clicked ${count} times`; - }); - - return ( -
    -

    You clicked {count} times

    - -
    - ); -} -``` - -当你调用`useEffect`,就是告诉React在刷新DOM之后运行你的副作用函数。副作用函数在组件中声明,所以可以使用组件的状态(state)和属性(props)。React默认在每一次渲染后运行副作用函数——*包括*第一次渲染。(与类组件的生命周期函数的对比请看[使用副作用钩子](/docs/hooks-effect.html)。) - -副作用函数可以通过返回一个函数来指定如何"回收"它们。举个例子,这个组件使用了一个副作用函数来订阅一个朋友的在线状态,通过取消订阅来回收: - -```js{10-16} -import { useState, useEffect } from 'react'; - -function FriendStatus(props) { - const [isOnline, setIsOnline] = useState(null); - - function handleStatusChange(status) { - setIsOnline(status.isOnline); - } - - useEffect(() => { - ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); - - return () => { - ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); - }; - }); - - if (isOnline === null) { - return 'Loading...'; - } - return isOnline ? 'Online' : 'Offline'; -} -``` - -在这个例子中,当组件被卸载时,React会在由随后的渲染引起的副作用函数运行之前取消对`ChatAPI`的订阅。(如果有需要的话,可以用这个方法[告诉React跳过重订阅](/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects)当传给`ChatAPI`的`props.friend.id`没有改变时。) - -像使用`useState`一样,你可以在一个组件中使用多个副作用: - -```js{3,8} -function FriendStatusWithCounter(props) { - const [count, setCount] = useState(0); - useEffect(() => { - document.title = `You clicked ${count} times`; - }); - - const [isOnline, setIsOnline] = useState(null); - useEffect(() => { - ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); - return () => { - ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); - }; - }); - - function handleStatusChange(status) { - setIsOnline(status.isOnline); - } - // ... -``` - -有了钩子,你可以在组件中按照代码块的相关性组织副作用,而不是基于生命周期方法强制进行切分。 - ->详细解释 -> ->你可以在这个页面上了解到更多关于`useEffect`的信息: [使用副作用钩子](/docs/hooks-effect.html)。 - -## ✌️ 钩子的使用规则 - -钩子就是强制实现了两条额外规则的Javascript函数: - -* 只能在*顶层*调用钩子。不要在循环,控制流和嵌套的函数中调用钩子。 -* 只能*从React的函数式组件中*调用钩子。不要在常规的JavaScript函数中调用钩子。(此外,你也可以在你的自定义钩子中调用钩子。我们马上就会讲到它。) - -我们提供了一个[语法检查插件](https://www.npmjs.com/package/eslint-plugin-react-hooks)以自动执行这些规则。我们能够理解开发者在一开始可能会对这些规则感到困惑或束手束脚,但它们正是保证钩子正确运行的基石。 - ->详细解释 -> ->你可以在这个页面上了解到更多关于这些规则的信息: [钩子的使用规则](/docs/hooks-rules.html)。 - -## 💡 构建你自己的钩子 - -有时你希望在组件之间复用一些状态逻辑。在之前有两种流行的解决方案:[高阶组件](/docs/higher-order-components.html) and [渲染属性](/docs/render-props.html)。现在你可以利用自定义钩子做到这些而不用在你的组件树中添加更多的组件。 - -在此之前,我们展示了一个`FriendStatus` 组件,它可以调用`useState`和`useEffect`钩子来订阅一个朋友的在线状态。假设我们想要在其他的组件中复用这个订阅逻辑。 - -首先,我们要把这个逻辑抽取到名为`useFriendStatus`的自定义钩子中: - -```js{3} -import { useState, useEffect } from 'react'; - -function useFriendStatus(friendID) { - const [isOnline, setIsOnline] = useState(null); - - function handleStatusChange(status) { - setIsOnline(status.isOnline); - } - - useEffect(() => { - ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange); - return () => { - ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange); - }; - }); - - return isOnline; -} -``` - -这个钩子需要一个`friendID`作为参数,返回你的朋友是否在线。 - -现在,我们可以同时在两个组件中使用它: - - -```js{2} -function FriendStatus(props) { - const isOnline = useFriendStatus(props.friend.id); - - if (isOnline === null) { - return 'Loading...'; - } - return isOnline ? 'Online' : 'Offline'; -} -``` - -```js{2} -function FriendListItem(props) { - const isOnline = useFriendStatus(props.friend.id); - - return ( -
  • - {props.friend.name} -
  • - ); -} -``` - -两个组件中的状态是完全独立的。钩子只复用状态逻辑而不是状态本身。事实上,每一次调用钩子都会得到一个完全孤立的状态——所以你甚至可以在同一个组件中使用两次相同的自定义钩子。 - -自定义钩子更多的是一个约定而不是特性。如果一个函数的名字以 "`use`" 开头并且调用了其他的钩子,我们就称它为自定义钩子。`useSomething`的命名约定方便语法检查插件找到代码中钩子的错误使用。 - -自定义钩子可以覆盖非常多的用例,像表单处理,动画,声明式订阅,定时器,还有很多我们还没有考虑到的。我们非常激动能够看到React社区提出的自定义钩子。 - ->详细解释 -> ->你可以在专门的页面上了解到更多关于自定义钩子的信息:[构建你自己的钩子](/docs/hooks-custom.html)。 - -## 🔌 其他钩子 - -还有一些不太常用的内置钩子,也许你会觉得非常有用。使用[`useContext`](/docs/hooks-reference.html#usecontext)可以订阅React context而不用引入嵌套: - -```js{2,3} -function Example() { - const locale = useContext(LocaleContext); - const theme = useContext(ThemeContext); - // ... -} -``` - -[`useReducer`](/docs/hooks-reference.html#usereducer)则允许你使用一个reducer来管理一个复杂组件的局部状态(local state): - -```js{2} -function Todos() { - const [todos, dispatch] = useReducer(todosReducer); - // ... -``` - ->详细解释 -> ->你可以在这个页面上了解到所有的内置钩子: [钩子API参考](/docs/hooks-reference.html)。 - -## 下一步 - -噢,太快了!如果有些地方没有讲清楚或者你想了解更多细节,你可以阅读下一页,从[状态钩子](/docs/hooks-state.html)这篇文档开始。 - -你也可以查看[钩子API参考](/docs/hooks-reference.html)和[钩子常见问题](/docs/hooks-faq.html)。 - -最后,不要错过[介绍页面](/docs/hooks-intro.html),这里解释了为什么我们要引入钩子以及我们如何同时使用类和钩子,而无需重写我们的应用。 diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md deleted file mode 100644 index afc3d3735e..0000000000 --- a/content/docs/hooks-reference.md +++ /dev/null @@ -1,358 +0,0 @@ ---- -id: hooks-reference -title: Hooks API Reference -permalink: docs/hooks-reference.html -prev: hooks-custom.html -next: hooks-faq.html ---- - -*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). - -This page describes the APIs for the built-in Hooks in React. - -If you're new to Hooks, you might want to check out [the overview](/docs/hooks-overview.html) first. You may also find useful information in the [frequently asked questions](/docs/hooks-faq.html) section. - -- [Basic Hooks](#basic-hooks) - - [`useState`](#usestate) - - [`useEffect`](#useeffect) - - [`useContext`](#usecontext) -- [Additional Hooks](#additional-hooks) - - [`useReducer`](#usereducer) - - [`useCallback`](#usecallback) - - [`useMemo`](#usememo) - - [`useRef`](#useref) - - [`useImperativeMethods`](#useimperativemethods) - - [`useMutationEffect`](#usemutationeffect) - - [`useLayoutEffect`](#uselayouteffect) - -## Basic Hooks - -### `useState` - -```js -const [state, setState] = useState(initialState); -``` - -Returns a stateful value, and a function to update it. - -During the initial render, the returned state (`state`) is the same as the value passed as the first argument (`initialState`). - -The `setState` function is used to update the state. It accepts a new state value and enqueues a re-render of the component. - -```js -setState(newState); -``` - -During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates. - -#### Functional updates - -If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`: - -```js -function Counter({initialCount}) { - const [count, setCount] = useState(initialCount); - return ( - - Count: {count} - - - - - ); -} -``` - -The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to 0. - -> Note -> -> Unlike the `setState` method found in class components, `useState` does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax: -> -> ```js -> setState(prevState => { -> // Object.assign would also work -> return {...prevState, ...updatedValues}; -> }); -> ``` -> -> Another option is `useReducer`, which is more suited for managing state objects that contain multiple sub-values. - -#### Lazy initialization - -The `initialState` argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render: - -```js -const [state, setState] = useState(() => { - const initialState = someExpensiveComputation(props); - return initialState; -}); -``` - -### `useEffect` - -```js -useEffect(didUpdate); -``` - -Accepts a function that contains imperative, possibly effectful code. - -Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React's _render phase_). Doing so will lead to confusing bugs and inconsistencies in the UI. - -Instead, use `useEffect`. The function passed to `useEffect` will run after the render is committed to the screen. Think of effects as an escape hatch from React's purely functional world into the imperative world. - -By default, effects run after every completed render, but you can choose to fire it [only when certain values have changed](#conditionally-firing-an-effect). - -#### Cleaning up an effect - -Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to `useEffect` may return a clean-up function. For example, to create a subscription: - -```js -useEffect(() => { - const subscription = props.source.subscribe(); - return () => { - // Clean up the subscription - subscription.unsubscribe(); - }; -}); -``` - -The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the **previous effect is cleaned up before executing the next effect**. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section. - -#### Timing of effects - -Unlike `componentDidMount` and `componentDidUpdate`, the function passed to `useEffect` fires **after** layout and paint, during a deferred event. This makes it suitable for the many common side effects, like setting up subscriptions and event handlers, because most types of work shouldn't block the browser from updating the screen. - -However, not all effects can be deferred. For example, a DOM mutation that is visible to the user must fire synchronously before the next paint so that the user does not perceive a visual inconsistency. (The distinction is conceptually similar to passive versus active event listeners.) For these types of effects, React provides two additional Hooks: [`useMutationEffect`](#usemutationeffect) and [`useLayoutEffect`](#uselayouteffect). These Hooks have the same signature as `useEffect`, and only differ in when they are fired. - -Although `useEffect` is deferred until after the browser has painted, it's guaranteed to fire before any new renders. React will always flush a previous render's effects before starting a new update. - -#### Conditionally firing an effect - -The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its inputs changes. - -However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only if the `source` props has changed. - -To implement this, pass a second argument to `useEffect` that is the array of values that the effect depends on. Our updated example now looks like this: - -```js -useEffect( - () => { - const subscription = props.source.subscribe(); - return () => { - subscription.unsubscribe(); - }; - }, - [props.source], -); -``` - -Now the subscription will only be recreated when `props.source` changes. - -Passing in an empty array `[]` of inputs tells React that your effect doesn't depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won't run on updates. - -> Note -> -> The array of inputs is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. - -### `useContext` - -```js -const context = useContext(Context); -``` - -Accepts a context object (the value returned from `React.createContext`) and returns the current context value, as given by the nearest context provider for the given context. - -When the provider updates, this Hook will trigger a rerender with the latest context value. - -## Additional Hooks - -The following Hooks are either variants of the basic ones from the previous section, or only needed for specific edge cases. Don't stress about learning them up front. - -### `useReducer` - -```js -const [state, dispatch] = useReducer(reducer, initialState); -``` - -An alternative to [`useState`](#usestate). Accepts a reducer of type `(state, action) => newState`, and returns the current state paired with a `dispatch` method. (If you're familiar with Redux, you already know how this works.) - -Here's the counter example from the [`useState`](#usestate) section, rewritten to use a reducer: - -```js -const initialState = {count: 0}; - -function reducer(state, action) { - switch (action.type) { - case 'reset': - return initialState; - case 'increment': - return {count: state.count + 1}; - case 'decrement': - return {count: state.count - 1}; - } -} - -function Counter({initialCount}) { - const [state, dispatch] = useReducer(reducer, initialState); - return ( - - Count: {state.count} - - - - - ); -} -``` - -#### Lazy initialization - -`useReducer` accepts an optional third argument, `initialAction`. If provided, the initial action is applied during the initial render. This is useful for computing an initial state that includes values passed via props: - -```js -const initialState = {count: 0}; - -function reducer(state, action) { - switch (action.type) { - case 'reset': - return {count: action.payload}; - case 'increment': - return {count: state.count + 1}; - case 'decrement': - return {count: state.count - 1}; - } -} - -function Counter({initialCount}) { - const [state, dispatch] = useReducer( - reducer, - initialState, - {type: 'reset', payload: initialCount}, - ); - - return ( - - Count: {state.count} - - - - - ); -} -``` - -`useReducer` is usually preferable to `useState` when you have complex state logic that involves multiple sub-values. It also lets you optimize performance for components that trigger deep updates because [you can pass `dispatch` down instead of callbacks](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down). - -### `useCallback` - -```js -const memoizedCallback = useCallback( - () => { - doSomething(a, b); - }, - [a, b], -); -``` - -Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback. - -Pass an inline callback and an array of inputs. `useCallback` will return a memoized version of the callback that only changes if one of the inputs has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`). - -`useCallback(fn, inputs)` is equivalent to `useMemo(() => fn, inputs)`. - -> Note -> -> The array of inputs is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. - -### `useMemo` - -```js -const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); -``` - -Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) value. - -Pass a "create" function and an array of inputs. `useMemo` will only recompute the memoized value when one of the inputs has changed. This optimization helps to avoid expensive calculations on every render. - -If no array is provided, a new value will be computed whenever a new function instance is passed as the first argument. (With an inline function, on every render.) - -> Note -> -> The array of inputs is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. - -### `useRef` - -```js -const refContainer = useRef(initialValue); -``` - -`useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. - -A common use case is to access a child imperatively: - -```js -function TextInputWithFocusButton() { - const inputEl = useRef(null); - const onButtonClick = () => { - // `current` points to the mounted text input element - inputEl.current.focus(); - }; - return ( - - - - - ); -} -``` - -Note that `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. - -### `useImperativeMethods` - -```js -useImperativeMethods(ref, createInstance, [inputs]) -``` - -`useImperativeMethods` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeMethods` should be used with `forwardRef`: - -```js -function FancyInput(props, ref) { - const inputRef = useRef(); - useImperativeMethods(ref, () => ({ - focus: () => { - inputRef.current.focus(); - } - })); - return ; -} -FancyInput = forwardRef(FancyInput); -``` - -In this example, a parent component that renders `` would be able to call `fancyInputRef.current.focus()`. - -### `useMutationEffect` - -The signature is identical to `useEffect`, but it fires synchronously during the same phase that React performs its DOM mutations, before sibling components have been updated. Use this to perform custom DOM mutations. - -Prefer the standard `useEffect` when possible to avoid blocking visual updates. - ->Note -> ->Avoid reading from the DOM in `useMutationEffect`. If you do, you can cause performance problems by introducing [layout thrash](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing). When reading computed styles or layout information, `useLayoutEffect` is more appropriate. - -### `useLayoutEffect` - -The signature is identical to `useEffect`, but it fires synchronously *after* all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. - -Prefer the standard `useEffect` when possible to avoid blocking visual updates. - -> Tip -> -> If you're migrating code from a class component, `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`, so if you're unsure of which effect Hook to use, it's probably the least risky. diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md deleted file mode 100644 index 731f619aaa..0000000000 --- a/content/docs/hooks-rules.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -id: hooks-rules -title: Rules of Hooks -permalink: docs/hooks-rules.html -next: hooks-custom.html -prev: hooks-effect.html ---- - -*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). - -Hooks are JavaScript functions, but you need to follow two rules when using them. We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically: - -### Only Call Hooks at the Top Level - -**Don't call Hooks inside loops, conditions, or nested functions.** Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That's what allows React to correctly preserve the state of Hooks between multiple `useState` and `useEffect` calls. (If you're curious, we'll explain this in depth [below](#explanation).) - -### Only Call Hooks from React Functions - -**Don't call Hooks from regular JavaScript functions.** Instead, you can: - -* ✅ Call Hooks from React function components. -* ✅ Call Hooks from custom Hooks (we'll learn about them [on the next page](/docs/hooks-custom.html)). - -By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code. - -## ESLint Plugin - -We released an ESLint plugin called [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces these two rules. You can add this plugin to your project if you'd like to try it: - -```bash -npm install eslint-plugin-react-hooks@next -``` - -```js -// Your ESLint configuration -{ - "plugins": [ - // ... - "react-hooks" - ], - "rules": { - // ... - "react-hooks/rules-of-hooks": "error" - } -} -``` - -In the future, we intend to include this plugin by default into Create React App and similar toolkits. - -**You can skip to the next page explaining how to write [your own Hooks](/docs/hooks-custom.html) now.** On this page, we'll continue by explaining the reasoning behind these rules. - -## Explanation - -As we [learned earlier](/docs/hooks-state.html#tip-using-multiple-state-variables), we can use multiple State or Effect Hooks in a single component: - -```js -function Form() { - // 1. Use the name state variable - const [name, setName] = useState('Mary'); - - // 2. Use an effect for persisting the form - useEffect(function persistForm() { - localStorage.setItem('formData', name); - }); - - // 3. Use the surname state variable - const [surname, setSurname] = useState('Poppins'); - - // 4. Use an effect for updating the title - useEffect(function updateTitle() { - document.title = name + ' ' + surname; - }); - - // ... -} -``` - -So how does React know which state corresponds to which `useState` call? The answer is that **React relies on the order in which Hooks are called**. Our example works because the order of the Hook calls is the same on every render: - -```js -// ------------ -// First render -// ------------ -useState('Mary') // 1. Initialize the name state variable with 'Mary' -useEffect(persistForm) // 2. Add an effect for persisting the form -useState('Poppins') // 3. Initialize the surname state variable with 'Poppins' -useEffect(updateTitle) // 4. Add an effect for updating the title - -// ------------- -// Second render -// ------------- -useState('Mary') // 1. Read the name state variable (argument is ignored) -useEffect(persistForm) // 2. Replace the effect for persisting the form -useState('Poppins') // 3. Read the surname state variable (argument is ignored) -useEffect(updateTitle) // 4. Replace the effect for updating the title - -// ... -``` - -As long as the order of the Hook calls is the same between renders, React can associate some local state with each of them. But what happens if we put a Hook call (for example, the `persistForm` effect) inside a condition? - -```js - // 🔴 We're breaking the first rule by using a Hook in a condition - if (name !== '') { - useEffect(function persistForm() { - localStorage.setItem('formData', name); - }); - } -``` - -The `name !== ''` condition is `true` on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition `false`. Now that we skip this Hook during rendering, the order of the Hook calls becomes different: - -```js -useState('Mary') // 1. Read the name state variable (argument is ignored) -// useEffect(persistForm) // 🔴 This Hook was skipped! -useState('Poppins') // 🔴 2 (but was 3). Fail to read the surname state variable -useEffect(updateTitle) // 🔴 3 (but was 4). Fail to replace the effect -``` - -React wouldn't know what to return for the second `useState` Hook call. React expected that the second Hook call in this component corresponds to the `persistForm` effect, just like during the previous render, but it doesn't anymore. From that point, every next Hook call after the one we skipped would also shift by one, leading to bugs. - -**This is why Hooks must be called on the top level of our components.** If we want to run an effect conditionally, we can put that condition *inside* our Hook: - -```js - useEffect(function persistForm() { - // 👍 We're not breaking the first rule anymore - if (name !== '') { - localStorage.setItem('formData', name); - } - }); -``` - -**Note that you don't need to worry about this problem if you use the [provided lint rule](https://www.npmjs.com/package/eslint-plugin-react-hooks).** But now you also know *why* Hooks work this way, and which issues the rule is preventing. - -## Next Steps - -Finally, we're ready to learn about [writing your own Hooks](/docs/hooks-custom.html)! Custom Hooks let you combine Hooks provided by React into your own abstractions, and reuse common stateful logic between different components. diff --git a/content/docs/hooks-state.md b/content/docs/hooks-state.md deleted file mode 100644 index f71cbc70aa..0000000000 --- a/content/docs/hooks-state.md +++ /dev/null @@ -1,315 +0,0 @@ ---- -id: hooks-state -title: Using the State Hook -permalink: docs/hooks-state.html -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). - -The [previous page](/docs/hooks-intro.html) introduced Hooks with this example: -下面这一页介绍了Hooks的一个示例 -```js{4-5} -import { useState } from 'react'; - -function Example() { - // Declare a new state variable, which we'll call "count" - const [count, setCount] = useState(0); - - return ( -
    -

    You clicked {count} times

    - -
    - ); -} -``` - -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 -class Example extends React.Component { - constructor(props) { - super(props); - this.state = { - count: 0 - }; - } - - render() { - return ( -
    -

    You clicked {this.state.count} times

    - -
    - ); - } -} -``` - -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) => { - // You can use Hooks here! - return
    ; -} -``` - -或者: - -```js -function Example(props) { - // You can use Hooks here! - return
    ; -} -``` - -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'; - -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) { - super(props); - this.state = { - count: 0 - }; - } -``` - -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'; - -function Example() { - // Declare a new state variable, which we'll call "count" - const [count, setCount] = useState(0); -``` - -**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'; - -function Example() { - // Declare a new state variable, which we'll call "count" - const [count, setCount] = useState(0); -``` - -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} - -``` - -In a function, we already have `setCount` and `count` as variables so we don't need `this`: -在函数中,我们已经有了`setCount`和`count`作为变量,所以我们需要`this` -```js{1} - -``` - -## Recap -## 重申 -Let's now **recap what we learned line by line** and check our understanding. -我们现在重新来一行一行理解刚才所讲的东西 - -```js{1,4,9} - 1: import { useState } from 'react'; - 2: - 3: function Example() { - 4: const [count, setCount] = useState(0); - 5: - 6: return ( - 7:
    - 8:

    You clicked {count} times

    - 9: -12:
    -13: ); -14: } -``` - -* **Line 1:** We import the `useState` Hook from React. It lets us keep local state in a function component. -* **Line 1:** 我们从React中导入`useState`钩子,它让我们将函数中的状态保存起来 -* **Line 4:** Inside the `Example` component, we declare a new state variable by calling the `useState` Hook. It returns a pair of values, to which we give names. We're calling our variable `count` because it holds the number of button clicks. We initialize it to zero by passing `0` as the only `useState` argument. The second returned item is itself a function. It lets us update the `count` so we'll name it `setCount`. -* **Line4:** 在`Example`组件中,我们通过`useState`声明了一个新的状态变量,它返回一对我们给定的值,我们把`count`定义为按钮点击的次数,初始化为零,写在`useState`的参数中,第二个值是一个函数,用来更新我们`count`。 -* **Line 9:** When the user clicks, we call `setCount` with a new value. React will then re-render the `Example` component, passing the new `count` value to it. -* **Line9:** 在用户点击的时候,调用`setCount`传入一个新的值,React会重新渲染`Examole`组件,同一时刻分配这个更新后的`count`值 -This might seem like a lot to take in at first. Don't rush it! If you're lost in the explanation, look at the code above again and try to read it from top to bottom. We promise that once you try to "forget" how state works in classes, and look at this code with fresh eyes, it will make sense. -这个看起来挺不容易理解的,但是不要着急,如果你对某些地方感觉还需要理清思路,重复阅读上面的代码,我们保证,一旦你试图将脑海中class声明的`this.state`的方式去除掉,再理解起来,就会很非常轻松。 -### Tip: What Do Square Brackets Mean? -### 小技巧:方括号是什么意思 -You might have noticed the square brackets when we declare a state variable: -你也许注意到变量声明时候的方括号 -```js - const [count, setCount] = useState(0); -``` - -The names on the left aren't a part of the React API. You can name your own state variables: -变量的声明不是ReactAPI的一部分,你可以命名自己的变量 -```js - const [fruit, setFruit] = useState('banana'); -``` - -This JavaScript syntax is called ["array destructuring"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring). It means that we're making two new variables `fruit` and `setFruit`, where `fruit` is set to the first value returned by `useState`, and `setFruit` is the second. It is equivalent to this code: -这个语法是ES6中的解构赋值["array destructuring"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring),表示我们定义了两个变量`fruit`和`setFruit`,`fruit`被设置为`useState`的第一个值,`setFruit`是第二个,等价于下代码 -```js - var fruitStateVariable = useState('banana'); // Returns a pair - var fruit = fruitStateVariable[0]; // First item in a pair - var setFruit = fruitStateVariable[1]; // Second item in a pair -``` - -When we declare a state variable with `useState`, it returns a pair — an array with two items. The first item is the current value, and the second is a function that lets us update it. Using `[0]` and `[1]` to access them is a bit confusing because they have a specific meaning. This is why we use array destructuring instead. -当我们使用`useState`声明状态变量,它返回一对,带有两个值的数组,第一个参数是变化的状态值,第二个是用来更新该状态的函数,使用`[0]`和`[1]`来访问会有一些困惑,因为它们有特定的含义,所以我们使用解构赋值来代替。 ->Note -> ->You might be curious how React knows which component `useState` corresponds to since we're not passing anything like `this` back to React. We'll answer [this question](/docs/hooks-faq.html#how-does-react-associate-hook-calls-with-components) and many others in the FAQ section. ->注意 -> ->你可能感到好奇,为何React知道哪个组件的`useState`,因为我们并没有将this之类的东西传递给React,在这里可以找到答案[this question](/docs/hooks-faq.html#how-does-react-associate-hook-calls-with-components) and many others in the FAQ section. -### Tip: Using Multiple State Variables -### 小技巧:使用多个状态变量 -Declaring state variables as a pair of `[something, setSomething]` is also handy because it lets us give *different* names to different state variables if we want to use more than one: -声明状态变量的一对值`[something, setSomething]`是很容易的,因为我们使用的是不同的命名,不同的名字返回更多的状态变量 -```js -function ExampleWithManyStates() { - // Declare multiple state variables! - const [age, setAge] = useState(42); - const [fruit, setFruit] = useState('banana'); - const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]); -``` - -In the above component, we have `age`, `fruit`, and `todos` as local variables, and we can update them individually: -在下面的这个组件中,有年龄,水果,待办事项,作为本地变量,我们可以分别声明它们 -```js - function handleOrangeClick() { - // Similar to this.setState({ fruit: 'orange' }) - setFruit('orange'); - } -``` - -You **don't have to** use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike `this.setState` in a class, updating a state variable always *replaces* it instead of merging it. -你 **不必** 使用很多状态变量,状态变量可以保持一个对象和一个数组,你也可以将相关联的数据组合到一起,然而,不像类中的`this.setState`,更新一个状态的值总是需要*替换*它,而不是合并它 -We provide more recommendations on splitting independent state variables [in the FAQ](/docs/hooks-faq.html#should-i-use-one-or-many-state-variables). -我们提供了更多的分离状态的推荐[in the FAQ](/docs/hooks-faq.html#should-i-use-one-or-many-state-variables). -## Next Steps -## 下一步 -On this page we've learned about one of the Hooks provided by React, called `useState`. We're also sometimes going to refer to it as the "State Hook". It lets us add local state to React function components -- which we did for the first time ever! -在这里我们已经学会了React提供的Hooks,叫做`useState`,我们有时候也将它称为"状态钩子",它让我们添加一个本地的状态给React的函数组件,就像之前那样。 -We also learned a little bit more about what Hooks are. Hooks are functions that let you "hook into" React features from function components. Their names always start with `use`, and there are more Hooks we haven't seen yet. -我们已经学会了一些关于钩子函数的东西,钩子函数是一个在函数式组件中使用React状态特性的函数,它们的名字通常以`use`开头,有更多的钩子函数我们会在后面看见。 -**Now let's continue by [learning the next Hook: `useEffect`.](/docs/hooks-effect.html)** It lets you perform side effects in components, and is similar to lifecycle methods in classes. -**接下来我们继续下一部分[learning the next Hook: `useEffect`.](/docs/hooks-effect.html)**它允许你在组件中使用一些副作用,类似于class中的生命周期函数。 diff --git a/content/docs/how-to-contribute.md b/content/docs/how-to-contribute.md old mode 100644 new mode 100755 diff --git a/content/docs/implementation-notes.md b/content/docs/implementation-notes.md old mode 100644 new mode 100755 diff --git a/content/docs/installation.md b/content/docs/installation.md deleted file mode 100644 index 4378992e78..0000000000 --- a/content/docs/installation.md +++ /dev/null @@ -1,8 +0,0 @@ -## 安装 -React 一开始就是梯度设计的,你可以按需调用: - -- 使用[在线的 Playgrounds](/docs/getting-started.html#online-playgrounds) 尝尝鲜 -- 快速地将 [React 添加到一个网站](/docs/add-react-to-a-website.html) 里 > 标签 -- 如果你期待一个功能强大的 JavaScript 工具链,请[创建一个全新的 React 应用](/docs/create-a-new-react-app.html) - -作为来自 [CDN](/docs/cdn-links.html) 的一个 > 标签,或者作为 [npm](https://www.npmjs.com) 里的一个 react 包,你都可以使用到 React diff --git a/content/docs/integrating-with-other-libraries.md b/content/docs/integrating-with-other-libraries.md old mode 100644 new mode 100755 diff --git a/content/docs/introducing-jsx.md b/content/docs/introducing-jsx.md old mode 100644 new mode 100755 index c001c35db1..3b2023a030 --- a/content/docs/introducing-jsx.md +++ b/content/docs/introducing-jsx.md @@ -76,7 +76,7 @@ const element = ; 也可以使用大括号来定义以 JavaScript 表达式为值的属性: ```js -const element = ; +const element = ; ``` 切记你使用了大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式。 diff --git a/content/docs/jsx-in-depth.md b/content/docs/jsx-in-depth.md old mode 100644 new mode 100755 index f376b0a03e..a146cbb9a0 --- a/content/docs/jsx-in-depth.md +++ b/content/docs/jsx-in-depth.md @@ -15,7 +15,7 @@ redirect_from: 本质上来讲,JSX 只是为 `React.createElement(component, props, ...children) ` 方法提供的语法糖。比如下面的代码: -```jsx +```js Click Me @@ -23,7 +23,7 @@ redirect_from: 编译为: -```jsx +```js React.createElement( MyButton, {color: 'blue', shadowSize: 2}, @@ -33,13 +33,13 @@ React.createElement( 如果没有子代,你还可以使用自闭合标签,比如: -```jsx +```js
    ``` 编译为: -```jsx +```js React.createElement( 'div', {className: 'sidebar'}, @@ -51,33 +51,33 @@ React.createElement( ## 指定 React 元素类型 -JSX 的标签的第一部分决定了 React 元素的类型。 +JSX 的标签名决定了 React 元素的类型。 -首字母大写的类型表示 JSX 标签引用到一个 React 组件。这些标签将会被编译为直接引用同名变量,所以如果你使用了 `` JSX 表达式,则 `Foo` 必须在作用域中。 +大写开头的 JSX 标签表示一个 React 组件。这些标签将会被编译为同名变量并被引用,所以如果你使用了 `` 表达式,则必须在作用域中先声明 `Foo` 变量。 -### React 必须在作用域中 +### React 必须声明 -由于 JSX 编译成`React.createElement`方法的调用,所以在你的 JSX 代码中,`React`库必须也始终在作用域中。 +由于 JSX 编译后会调用 `React.createElement` 方法,所以在你的 JSX 代码中必须首先声明 `React` 变量。 比如,下面两个导入都是必须的,尽管 `React` 和 `CustomButton` 都没有在代码中被直接调用。 -```jsx{1,2,5} +```js{1,2,5} import React from 'react'; import CustomButton from './CustomButton'; function WarningButton() { - // return React.createElement(CustomButton, {color: 'red'}, null); + // 返回 React.createElement(CustomButton, {color: 'red'}, null); return ; } ``` -如果你没有使用JavaScript 打捆机,而是从`>`标签加载React,它已经在作用域中,以`React`全局变量的形式。 +如果你使用 `>` 加载 React,它将作用于全局。 -### 点表示法用于JSX类型 +### 点表示法 你还可以使用 JSX 中的点表示法来引用 React 组件。你可以方便地从一个模块中导出许多 React 组件。例如,有一个名为 `MyComponents.DatePicker` 的组件,你可以直接在 JSX 中使用它: -```jsx{10} +```js{10} import React from 'react'; const MyComponents = { @@ -91,15 +91,15 @@ function BlueDatePicker() { } ``` -### 用户定义组件必须首字母大写 +### 首字母大写 -当元素类型以小写字母开头时,它表示一个内置的组件,如 `
    ` 或 ``,将导致字符串 `'div'` 或 `'span'` 传递给 `React.createElement`。 以大写字母开头的类型,如 `` 编译为 `React.createElement(Foo)`,并且它正对应于你在 JavaScript 文件中定义或导入的组件。 +当元素类型以小写字母开头时,它表示一个内置的组件,如 `
    ` 或 ``,并将字符串 'div' 或 'span' 传 递给 `React.createElement`。 以大写字母开头的类型,如 `` 编译为 `React.createElement(Foo)`,并它正对应于你在 JavaScript 文件中定义或导入的组件。 我们建议用大写开头命名组件。如果你的组件以小写字母开头,请在 JSX 中使用之前其赋值给大写开头的变量。 例如,下面的代码将无法按预期运行: -```jsx{3,4,10,11} +```js{3,4,10,11} import React from 'react'; // 错误!组件名应该首字母大写: @@ -116,7 +116,7 @@ function HelloWorld() { 为了解决这个问题,我们将 `hello` 重命名为 `Hello`,然后使用 `` 引用: -```jsx{3,4,10,11} +```js{3,4,10,11} import React from 'react'; // 正确!组件名应该首字母大写: @@ -133,9 +133,9 @@ function HelloWorld() { ### 在运行时选择类型 -你不能使用一个通用的表达式来作为 React 元素的标签。如果你的确想使用一个通用的表达式来确定 React 元素的类型,请先将其赋值给大写开头的变量。这种情况一般发生于当你想基于属性值渲染不同的组件时: +你不能使用表达式来作为 React 元素的标签。如果你的确想通过表达式来确定 React 元素的类型,请先将其赋值给大写开头的变量。这种情况一般会在你想通过属性值条件渲染组件时出现: -```jsx{10,11} +```js{10,11} import React from 'react'; import { PhotoStory, VideoStory } from './stories'; @@ -152,7 +152,7 @@ function Story(props) { 要解决这个问题,我们需要先将类型赋值给大写开头的变量。 -```jsx{10-12} +```js{10-12} import React from 'react'; import { PhotoStory, VideoStory } from './stories'; @@ -168,23 +168,23 @@ function Story(props) { } ``` -## JSX的属性(Props) +## 属性 在 JSX 中有几种不同的方式来指定属性。 -### 使用 JavaScript 表达式作为属性 +### 使用 JavaScript 表达式 -你可以传递JavaScript 表达式作为一个属性,再用大括号`{}`括起来。例如,在这个 JSX 中: +你可以传递任何 `{}` 包裹的 JavaScript 表达式作为一个属性值。例如,在这个 JSX 中: -```jsx +```js ``` 对于 `MyComponent`来说, `props.foo` 的值为 10,这是 `1 + 2 + 3 + 4` 表达式计算得出的。 -`if` 语句和 `for` 循环在 JavaScript 中不是表达式,因此它们不能直接在 JSX 中使用,但是你可以将它们放在周围的代码中。例如: +`if` 语句和 `for` 循环在 JavaScript 中不是表达式,因此它们不能直接在 JSX 中使用,但是你可以将它们放在周围的代码中。 -```jsx{3-7} +```js{3-7} function NumberDescriber(props) { let description; if (props.number % 2 == 0) { @@ -202,15 +202,15 @@ function NumberDescriber(props) { 你可以将字符串常量作为属性值传递。下面这两个 JSX 表达式是等价的: -```jsx +```js ``` -当传递一个字符串常量时,该值为HTML非转义的,所以下面两个 JSX 表达式是相同的: +当传递一个字符串常量时,该值会被解析为HTML非转义字符串,所以下面两个 JSX 表达式是相同的: -```jsx +```js @@ -218,11 +218,11 @@ function NumberDescriber(props) { 这种行为通常是无意义的,提到它只是为了完整性。 -### 属性默认为"True" +### 默认为 True 如果你没有给属性传值,它默认为 `true`。因此下面两个 JSX 是等价的: -```jsx +```js @@ -230,11 +230,11 @@ function NumberDescriber(props) { 一般情况下,我们不建议这样使用,因为它会与 [ES6 对象简洁表示法](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015) 混淆。比如 `{foo}` 是 `{foo: foo}` 的简写,而不是 `{foo: true}`。这里能这样用,是因为它符合 HTML 的做法。 -### 展开属性 +### 扩展属性 -如果你已经有了个 `props` 对象,并且想在 JSX 中传递它,你可以使用 `...` 作为"展开(spread)"操作符来传递整个属性对象。下面两个组件是等效的: +如果你已经有了个 `props` 对象,并且想在 JSX 中传递它,你可以使用 `...` 作为扩展操作符来传递整个属性对象。下面两个组件是等效的: -```jsx{7} +```js{7} function App1() { return ; } @@ -245,39 +245,17 @@ function App2() { } ``` -你也可以选取特定属性对象来被组件使用,同时使用"展开(spread)"操作符将其他属性传递下去。 +当你构建通用容器时,扩展属性会非常有用。然而,这样做也可能让很多不相关的属性,传递到不需要它们的组件中使代码变得混乱。我们建议你谨慎使用此语法。 -```jsx -const Button = props => { - const { kind, ...other } = props; - const className = kind === "primary" ? "PrimaryButton" : "SecondaryButton"; - return -
    - ); -}; -``` +## 子代 -在上述例子中,`kind` 属性被安全地使用,不会传递到DOM中的 `