diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b2fd96578..9e5a7c928 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,8 +14,9 @@ If your PR references an existing issue, please add the issue number below ## Progress -- [ ] 번역 초안 작성(Draft translation) -- [ ] [공통 스타일 가이드 확인 (Check the common style guide)](link) -- [ ] [용어 확인 (Check the term)](link) +- [ ] 번역 초안 작성 (Draft translation) +- [ ] [공통 스타일 가이드 확인 (Check the common style guide)](https://github.com/reactjs/ko.reactjs.org/blob/master/UNIVERSAL-STYLE-GUIDE.md) +- [ ] [모범사례 확인 (Check best practices)](https://github.com/reactjs/ko.reactjs.org/wiki/Best-practices-for-translation) +- [ ] [용어 확인 (Check the term)](https://github.com/reactjs/ko.reactjs.org/wiki/Translate-Glossary) - [ ] [맞춤법 검사 (Spelling check)](http://speller.cs.pusan.ac.kr/) - [ ] 리뷰 반영 (Resolve reviews) diff --git a/README.md b/README.md index 3044c0d66..aa3c960ef 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,70 @@ # reactjs.org -This repo contains the source code and documentation powering [reactjs.org](https://reactjs.org/). +이 저장소는 [reactjs.org](https://reactjs.org/)의 소스 코드와 개발 문서를 포함하고 있습니다. -## Getting started +## 시작하기 -### Prerequisites +### 사전 준비 1. Git -1. Node: any 8.x version starting with 8.4.0 or greater -1. Yarn: See [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/) -1. A fork of the repo (for any contributions) -1. A clone of the [reactjs.org repo](https://github.com/reactjs/reactjs.org) on your local machine +1. Node: 8.4.0 이상으로 시작하는 모든 8.x 버전 +1. Yarn: [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/) 참고 +1. 포크한 개인 저장소 +1. 로컬에 클론(Clone) 한 [reactjs.org repo](https://github.com/reactjs/reactjs.org) 개인 저장소 -### Installation +### 설치 -1. `cd reactjs.org` to go into the project root -1. `yarn` to install the website's npm dependencies +1. `cd reactjs.org`를 실행하여 프로젝트 경로로 이동합니다. +1. `yarn`을 이용하여 npm 의존성 모듈들을 설치합니다. -### Running locally +### 개발 서버 실행하기 -1. `yarn dev` to start the hot-reloading development server (powered by [Gatsby](https://www.gatsbyjs.org)) -1. `open http://localhost:8000` to open the site in your favorite browser +1. `yarn dev` 명령어를 사용하여 hot-reloading 개발 서버를 시작합니다. (powered by [Gatsby](https://www.gatsbyjs.org)) +1. `open http://localhost:8000` 명령어를 사용하여 선호하는 브라우저로 접속하세요. -## Contributing +## 기여방법 -### Guidelines +### 가이드라인 -The documentation is divided into several sections with a different tone and purpose. If you plan to write more than a few sentences, you might find it helpful to get familiar with the [contributing guidelines](https://github.com/reactjs/reactjs.org/blob/master/CONTRIBUTING.md#guidelines-for-text) for the appropriate sections. +이 문서는 목적이 다른 여러 섹션으로 나뉘게 됩니다. 문장을 추가할 계획이라면, 적절한 섹션에 대한 [가이드라인](https://github.com/reactjs/reactjs.org/blob/master/CONTRIBUTING.md#guidelines-for-text)을 숙지하는 것이 도움이 될 것입니다. -### Create a branch +### 브랜치(branch) 만들기 -1. `git checkout master` from any folder in your local `reactjs.org` repository -1. `git pull origin master` to ensure you have the latest main code -1. `git checkout -b the-name-of-my-branch` (replacing `the-name-of-my-branch` with a suitable name) to create a branch +1. `reactjs.org` 로컬 저장소에서 `git checkout master`를 실행합니다. +1. `git pull origin master`를 실행하여 최신 원본 코드를 보장할 수 있습니다. +1. `git checkout -b the-name-of-my-branch` (`the-name-of-my-branch` 를 적절한 이름으로 교체)를 실행하여 브랜치를 만듭니다. -### Make the change +### 수정하기 -1. Follow the "Running locally" instructions -1. Save the files and check in the browser - 1. Changes to React components in `src` will hot-reload - 1. Changes to markdown files in `content` will hot-reload - 1. If working with plugins, you may need to remove the `.cache` directory and restart the server +1. "개발 서버 실행하기" 부분을 따릅니다. +1. 파일을 저장하고 브라우저에서 확인합니다. + 1.`src`안에 있는 React 컴포넌트가 수정될 경우 hot-reload가 적용됩니다. + 1. `content`안에 있는 마크다운 파일이 수정될 경우 hot-reload가 적용됩니다. + 1. 플러그인을 사용하는 경우, `.cache` 디렉토리를 제거한 후 서버를 재시작해야 합니다. -### Test the change +### 수정사항 체크하기 -1. If possible, test any visual changes in all latest versions of common browsers, on both desktop and mobile. -1. Run `yarn check-all` from the project root. (This will run Prettier, ESLint, and Flow.) +1. 가능하다면, 변경한 부분에 대해서 많이 사용하는 브라우저의 최신 버전에서 시각적으로 제대로 적용되었는지 확인해주세요. (데스크탑과 모바일 모두) +1. 프로젝트 루트에서 `yarn check-all`를 실행합니다. (이 명령어는 Prettier, ESLint, 그리고 Flow를 실행합니다.) -### Push it +### Push 하기 -1. `git add -A && git commit -m "My message"` (replacing `My message` with a commit message, such as `Fixed header logo on Android`) to stage and commit your changes +1. `git add -A && git commit -m "My message"` (`My message` 부분을 `Fixed header logo on Android` 같은 커밋 메시지로 교체)를 실행하여 변경한 파일들을 commit 해주세요. 1. `git push my-fork-name the-name-of-my-branch` -1. Go to the [reactjs.org repo](https://github.com/reactjs/reactjs.org) and you should see recently pushed branches. -1. Follow GitHub's instructions. -1. If possible, include screenshots of visual changes. A Netlify build will also be automatically created once you make your PR so other people can see your change. +1. [reactjs.org repo](https://github.com/reactjs/reactjs.org)에서 최근에 푸시된 브랜치를 볼 수 있습니다. +1. Github 지침을 따라주세요. +1. 가능하다면 시각적으로 변화된 부분의 스크린샷을 첨부해주세요. PR을 만들고 다른사람들이 수정사항을 볼 수 있게되면, Netlify가 자동적으로 빌드할 것입니다. -## Translation +## 변역 -If you are interested in translating `reactjs.org`, please see the current translation efforts at [isreacttranslatedyet.com](https://www.isreacttranslatedyet.com/). +`reactjs.org` 번역에 흥미가 있다면, [isreacttranslatedyet.com](https://www.isreacttranslatedyet.com/)에서 현재 번역이 얼마나 진행되었는지 확인해주세요. -If your language does not have a translation and you would like to create one, please follow the instructions at [reactjs.org Translations](https://github.com/reactjs/reactjs.org-translation#translating-reactjsorg). +번역하려는 언어가 아직 진행되지 않았다면, 해당 언어에 대해 새롭게 만들 수 있습니다. [reactjs.org Translations](https://github.com/reactjs/reactjs.org-translation#translating-reactjsorg)를 참고해주세요. -## Troubleshooting +## 문제 해결하기 -- `yarn reset` to clear the local cache +- `yarn reset` 명령어를 사용하여 로컬 캐시를 초기화합니다. -## License -Content submitted to [reactjs.org](https://reactjs.org/) is CC-BY-4.0 licensed, as found in the [LICENSE-DOCS.md](https://github.com/open-source-explorer/reactjs.org/blob/master/LICENSE-DOCS.md) file. +## 저작권 +위 내용에 대한 저작권은 [reactjs.org](https://reactjs.org/)가 가지고 있으며, [LICENSE-DOCS.md](https://github.com/open-source-explorer/reactjs.org/blob/master/LICENSE-DOCS.md)에서 볼 수 있는 CC-BY-4.0 라이센스를 따릅니다. diff --git a/content/authors.yml b/content/authors.yml index da8efd3a7..5848c65e8 100644 --- a/content/authors.yml +++ b/content/authors.yml @@ -73,6 +73,9 @@ sophiebits: steveluscher: name: Steven Luscher url: https://twitter.com/steveluscher +tesseralis: + name: Nat Alison + url: https://twitter.com/tesseralis timer: name: Joe Haddad url: https://twitter.com/timer150 diff --git a/content/blog/2018-11-27-react-16-roadmap.md b/content/blog/2018-11-27-react-16-roadmap.md index d8a2f3982..4588af8be 100644 --- a/content/blog/2018-11-27-react-16-roadmap.md +++ b/content/blog/2018-11-27-react-16-roadmap.md @@ -87,7 +87,7 @@ function Example() { } ``` -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). +Hooks [introduction](/docs/hooks-intro.html) and [Hook 개요](/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. diff --git a/content/blog/2019-02-06-react-v16.8.0.md b/content/blog/2019-02-06-react-v16.8.0.md index 3af12da7d..72fee3e8a 100644 --- a/content/blog/2019-02-06-react-v16.8.0.md +++ b/content/blog/2019-02-06-react-v16.8.0.md @@ -12,7 +12,7 @@ Hooks let you use state and other React features without writing a class. You ca If you've never heard of Hooks before, you might find these resources interesting: * [Introducing Hooks](/docs/hooks-intro.html) explains why we're adding Hooks to React. -* [Hooks at a Glance](/docs/hooks-overview.html) is a fast-paced overview of the built-in Hooks. +* [Hook 개요](/docs/hooks-overview.html) is a fast-paced overview of the built-in Hooks. * [Building Your Own Hooks](/docs/hooks-custom.html) demonstrates code reuse with custom Hooks. * [Making Sense of React Hooks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) explores the new possibilities unlocked by Hooks. * [useHooks.com](https://usehooks.com/) showcases community-maintained Hooks recipes and demos. diff --git a/content/blog/2019-02-23-is-react-translated-yet.md b/content/blog/2019-02-23-is-react-translated-yet.md new file mode 100644 index 000000000..3ac56a5a4 --- /dev/null +++ b/content/blog/2019-02-23-is-react-translated-yet.md @@ -0,0 +1,76 @@ +--- +title: "Is React Translated Yet? ¡Sí! Sim! はい!" +author: [tesseralis] +--- + +We’re excited to announce an ongoing effort to maintain official translations of the React documentation website into different languages. Thanks to the dedicated efforts of React community members from around the world, React is now being translated into *over 30* languages! You can find them on the new [Languages](/languages) page. + +In addition, the following three languages have completed translating most of the React Docs! 🎉 + +* **Spanish: [es.reactjs.org](https://es.reactjs.org)** +* **Japanese: [ja.reactjs.org](https://ja.reactjs.org)** +* **Brazilian Portuguese: [pt-br.reactjs.org](https://pt-br.reactjs.org)** + +Special congratulations to [Alejandro Ñáñez Ortiz](https://github.com/alejandronanez), [Rainer Martínez Fraga](https://github.com/carburo), [David Morales](https://github.com/dmorales), [Miguel Alejandro Bolivar Portilla](https://github.com/Darking360), and all the contributors to the Spanish translation for being the first to *completely* translate the core pages of the docs! + +## Why Localization Matters {#why-localization-matters} + +React already has many meetups and conferences around the world, but many programmers don't use English as their primary language. We’d love to support local communities who use React by making our documentation available in most popular languages. + +In the past, React community members have created unofficial translations for [Chinese](https://github.com/discountry/react), [Arabic](https://wiki.hsoub.com/React), and [Korean](https://github.com/reactjs/ko.reactjs.org/issues/4); by making an official channel for these translated docs we're hoping to make them easier to find and help make sure that non-English-speaking users of React aren't left behind. + +## Contributing {#contributing} + +If you would like to help out on a current translation, check out the [Languages](/languages) page and click on the "Contribute" link for your language. + +Can't find your language? If you'd like to maintain your langauge's translation fork, follow the instructions in the [translation repo](https://github.com/reactjs/reactjs.org-translation#starting-a-new-translation)! + +## Backstory {#backstory} + +Hi everyone! I'm [Nat](https://twitter.com/tesseralis)! You may know me as the [polyhedra lady](https://www.youtube.com/watch?v=Ew-UzGC8RqQ). For the past few weeks, I've been helping the React team coordinate their translation effort. Here's how I did it. + +Our original approach for translations was to use a SaaS platform that allows users to submit translations. There was already a [pull request](https://github.com/reactjs/reactjs.org/pull/873) to integrate it and my original responsibility was to finish that integration. However, we had concerns about the feasibility of that integration and the current quality of translations on the platform. Our primary concern was ensuring that translations kept up to date with the main repo and didn't become "stale". + +[Dan](https://twitter.com/dan_abramov) encouraged me to look for alternate solutions, and we stumbled across how [Vue](https://vuejs.org) maintained its translations -- through different forks of the main repo on GitHub. In particular, the [Japanese translation](https://jp.vuejs.org) used a bot to periodically check for changes in the English repo and submits pull requests whenever there is a change. + +This approach appealed to us for several reasons: + +* It was less code integration to get off the ground. +* It encouraged active maintainers for each repo to ensure quality. +* Contributors already understand GitHub as a platform and are motivated to contribute directly to the React organization. + +We started of with an initial trial period of three languages: Spanish, Japanese, and Simplified Chinese. This allowed us to work out any kinks in our process and make sure future translations are set up for success. I wanted to give the translation teams freedom to choose whatever tools they felt comfortable with. The only requirement is a [checklist](https://github.com/reactjs/reactjs.org-translation/blob/master/PROGRESS.template.md) that outlines the order of importance for translating pages. + +After the trial period, we were ready to accept more languages. I created [a script](https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/create.js) to automate the creation of the new language repo, and a site, [Is React Translated Yet?](https://isreacttranslatedyet.com), to track progress on the different translations. We started *10* new translations on our first day alone! + +Because of the automation, the rest of the maintenance went mostly smoothly. We eventually created a [Slack channel](https://rt-slack-invite.herokuapp.com) to make it easier for translators to share information, and I released a guide solidifying the [responsibilities of maintainers](https://github.com/reactjs/reactjs.org-translation/blob/master/maintainer-guide.md). Allowing translators to talk with each other was a great boon -- for example, the Arabic, Persian, and Hebrew translations were able to talk to each other in order to get [right-to-left text](https://en.wikipedia.org/wiki/Right-to-left) working! + +## The Bot {#the-bot} + +The most challenging part was getting the bot to sync changes from the English version of the site. Initially we were using the [che-tsumi](https://github.com/vuejs-jp/che-tsumi) bot created by the Japanese Vue translation team, but we soon decided to build our own bot to suit our needs. In particular, the che-tsumi bot works by [cherry picking](https://git-scm.com/docs/git-cherry-pick) new commits. This ended up causing a cavalade of new issues that were interconnected, especially when [Hooks were released](/blog/2019/02/06/react-v16.8.0.html). + +In the end, we decided that instead of cherry picking each commit, it made more sense to merge all new commits and create a pull request around once a day. Conflicts are merged as-is and listed in the [pull request](https://github.com/reactjs/pt-BR.reactjs.org/pull/114), leaving a checklist for maintainers to fix. + +Creating the [sync script](https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/sync.js) was easy enough: it downloads the translated repo, adds the original as a remote, pulls from it, merges the conflicts, and creates a pull request. + +The problem was finding a place for the bot to run. I'm a frontend developer for a reason -- Heroku and its ilk are alien to me and *endlessly* frustrating. In fact, until this past Tuesday, I was running the script by hand on my local machine! + +The biggest challenge was space. Each fork of the repo is around 100MB -- which takes minutes to clone on my local machine. We have *32* forks, and the free tiers or most deployment platforms I checked limited you to 512MB of storage. + +After lots of notepad calculations, I found a solution: delete each repo once we've finished the script and limit the concurrency of `sync` scripts that run at once to be within the storage requirements. Luckily, Heroku dynos have a much faster Internet connection and are able to clone even the React repo quickly. + +There were other smaller issues that I ran into. I tried using the [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) add-on so I didn't have to write any actual `watch` code, but it end up running too inconsistently, and I [had an existential meltdown on Twitter](https://twitter.com/tesseralis/status/1097387938088796160) when I couldn't figure out how to send commits from the Heroku dyno. But in the end, this frontend engineer was able to get the bot working! + +There are, as always, improvements I want to make to the bot. Right now it doesn't check whether there is an outstanding pull request before pushing another one. It's still hard to tell the exact change that happened in the original source, and it's possible to miss out on a needed translation change. But I trust the maintainers we've chosen to work through these issues, and the bot is [open source](https://github.com/reactjs/reactjs.org-translation) if anyone wants to help me make these improvements! + +## Thanks {#thanks} + +Finally, I would like to extend my gratitude to the following people and groups: + + * All the translation maintainers and contributors who are helping translate React to more than thirty languages. + * The [Vue.js Japan User Group](https://github.com/vuejs-jp) for initiating the idea of having bot-managed translations, and especially [Hanatani Takuma](https://github.com/potato4d) for helping us understand their approach and helping maintain the Japanese translation. + * [Soichiro Miki](https://github.com/smikitky) for many [contributions](https://github.com/reactjs/reactjs.org/pull/1636) and thoughtful comments on the overall translation process, as well as for maintaining the Japanese translation. + * [Eric Nakagawa](https://github.com/ericnakagawa) for managing our previous translation process. + * [Brian Vaughn](https://github.com/bvaughn) for setting up the [languages page](/languages) and managing all the subdomains. + + And finally, thank you to [Dan Abramov](https://twitter.com/dan_abramov) for giving me this opportunity and being a great mentor along the way. diff --git a/content/community/conferences.md b/content/community/conferences.md index 62ac39b40..47fc57a0c 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -12,24 +12,15 @@ Do you know of a local React.js conference? Add it here! (Please keep the list c ## Upcoming Conferences {#upcoming-conferences} -### React Iran 2019 {#react-iran-2019} -January 31, 2019 in Tehran, Iran -[Website](http://reactiran.com) - [Instagram](https://www.instagram.com/reactiran/) - -### Reactathon 2019 {#reactathon-2019} -March 30-31, 2019 in San Francisco, USA +### ReactJS Girls Conference +May 3, 2019 in London, UK -[Website](https://www.reactathon.com/) - [Twitter](https://twitter.com/reactathon) +[Website](https://reactjsgirls.com/) - [Twitter](https://twitter.com/reactjsgirls) -### App.js Conf 2019 {#appjs-conf-2019} -April 4-5, 2019 in Kraków, Poland +### 2019 {#reactnotaconf--2019} +May 11 in Sofia, Bulgaria -[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) - -### React Amsterdam 2019 {#react-amsterdam-2019} -April 12, 2019 in Amsterdam, The Netherlands - -[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Facebook](https://www.facebook.com/reactamsterdam) +[Website](http://react-not-a-conf.com/) - [Twitter](https://twitter.com/reactnotaconf) - [Facebook](https://www.facebook.com/events/780891358936156) ### ReactEurope 2019 {#reacteurope-2019} May 23-24, 2019 in Paris, France @@ -51,8 +42,19 @@ June 21, 2019 Chicago, Illinois USA [Website](https://reactloop.com) - [Twitter](https://twitter.com/ReactLoop) +### Chain React 2019 +July 11-12, 2019. Portland, OR, USA. + +[Website](https://infinite.red/ChainReactConf) + +### React Rally 2019 +August 22-23, 2019. Salt Lake City, USA. + +[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/) + ### ComponentsConf 2019 {#componentsconf-2019} September 6, 2019 in Melbourne, Australia + [Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf) ### React Native EU 2019 {#react-native-eu-2019} @@ -70,6 +72,21 @@ September 26-28, 2019 in Goa, India [Website](https://www.reactindia.io/) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) +### React Alicante 2019 {#react-alicante-2019} +September 26-28, 2019 in Alicante, Spain + +[Website](http://reactalicante.es/) - [Twitter](https://twitter.com/reactalicante) - [Facebook](https://www.facebook.com/ReactAlicante) + +### React Advanced 2019 {#react-advanced-2019} +October 25, 2019 in London, UK + +[Website](https://reactadvanced.com) - [Twitter](http://twitter.com/reactadvanced) - [Facebook](https://www.facebook.com/ReactAdvanced) - [Videos](https://youtube.com/c/ReactConferences) + +### React Day Berlin 2019 {#react-day-berlin-2019} +December 6, 2019 in Berlin, Germany + +[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://www.youtube.com/reactdayberlin) + ## Past Conferences {#past-conferences} ### React.js Conf 2015 {#reactjs-conf-2015} @@ -97,7 +114,7 @@ February 22 & 23 in San Francisco, CA ### React Amsterdam 2016 {#react-amsterdam-2016} April 16 in Amsterdam, The Netherlands -[Website](https://react.amsterdam/2016) - [Videos](https://youtu.be/sXDZBxbRRag?list=PLNBNS7NRGKMG3uLrm5fgY02hJ87Wzb4IU) +[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Facebook](https://www.facebook.com/reactamsterdam) - [Videos](https://youtube.com/c/ReactConferences) ### ReactEurope 2016 {#reacteurope-2016} June 2 & 3 in Paris, France @@ -147,7 +164,7 @@ March 28th at the [QEII Centre, London](http://qeiicentre.london/) ### React Amsterdam 2017 {#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) - [Videos](https://youtube.com/c/ReactConferences) ### ReactEurope 2017 {#reacteurope-2017} May 18th & 19th in Paris, France @@ -338,3 +355,23 @@ November 4 in Tel Aviv, Israel November 30, Berlin, Germany [Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://www.youtube.com/channel/UC1EYHmQYBUJjkmL6OtK4rlw) + +### React Iran 2019 {#react-iran-2019} +January 31, 2019 in Tehran, Iran + +[Website](http://reactiran.com) - [Instagram](https://www.instagram.com/reactiran/) + +### Reactathon 2019 {#reactathon-2019} +March 30-31, 2019 in San Francisco, USA + +[Website](https://www.reactathon.com/) - [Twitter](https://twitter.com/reactathon) + +### App.js Conf 2019 {#appjs-conf-2019} +April 4-5, 2019 in Kraków, Poland + +[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) + +### React Amsterdam 2019 {#react-amsterdam-2019} +April 12, 2019 in Amsterdam, The Netherlands + +[Website](https://react.amsterdam) - [Twitter](https://twitter.com/reactamsterdam) - [Facebook](https://www.facebook.com/reactamsterdam) - [Videos](https://youtube.com/c/ReactConferences) diff --git a/content/community/examples.md b/content/community/examples.md index 09606a27d..9df2be352 100644 --- a/content/community/examples.md +++ b/content/community/examples.md @@ -11,10 +11,10 @@ There are many example projects created by the React community. Feel free to add * **[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. +* **[Github Battle App](https://tm.dev/react-course-project/)** 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 +* **[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. diff --git a/content/community/meetups.md b/content/community/meetups.md index d397a4535..8bd1155d0 100644 --- a/content/community/meetups.md +++ b/content/community/meetups.md @@ -88,6 +88,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet ## Pakistan {#pakistan} * [Karachi](https://www.facebook.com/groups/902678696597634/) +* [Lahore](https://www.facebook.com/groups/ReactjsLahore/) ## Peru {#peru} * [Lima](https://www.meetup.com/ReactJS-Peru/) @@ -130,8 +131,8 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [New York, NY - ReactJS](https://www.meetup.com/NYC-Javascript-React-Group/) * [New York, NY - React Ladies](https://www.meetup.com/React-Ladies/) * [New York, NY - React Native](https://www.meetup.com/React-Native-NYC/) -* [New York, NY - ReactNYC](https://www.meetup.com/ReactNYC/) * [Palo Alto, CA - React Native](https://www.meetup.com/React-Native-Silicon-Valley/) +* [Philadelphia, PA - ReactJS](https://www.meetup.com/RQ-React/) * [Phoenix, AZ - ReactJS](https://www.meetup.com/ReactJS-Phoenix/) * [Pittsburgh, PA - ReactJS/React Native](https://www.meetup.com/ReactPgh/) * [Portland, OR - ReactJS](https://www.meetup.com/Portland-ReactJS/) diff --git a/content/docs/add-react-to-a-website.md b/content/docs/add-react-to-a-website.md index 6a668e0a1..a97b44d45 100644 --- a/content/docs/add-react-to-a-website.md +++ b/content/docs/add-react-to-a-website.md @@ -110,7 +110,7 @@ Commonly, you might want to display React components in multiple places on the H ### Tip: Minify JavaScript for Production {#tip-minify-javascript-for-production} -Before deploying your website to production, be mindful that unminifed JavaScript can significantly slow down the page for your users. +Before deploying your website to production, be mindful that unminified JavaScript can significantly slow down the page for your users. If you already minify the application scripts, **your site will be production-ready** if you ensure that the deployed HTML loads the versions of React ending in `production.min.js`: diff --git a/content/docs/addons-shallow-compare.md b/content/docs/addons-shallow-compare.md index 99af2495c..44bee0cf3 100644 --- a/content/docs/addons-shallow-compare.md +++ b/content/docs/addons-shallow-compare.md @@ -8,7 +8,7 @@ category: Reference > Note: > -> `shallowCompare` is a legacy add-on. Use [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead. +> `shallowCompare` is a legacy add-on. Use [`React.memo`](/docs/react-api.html#reactmemo) or [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) instead. **Importing** diff --git a/content/docs/addons-shallow-renderer.md b/content/docs/addons-shallow-renderer.md index 7b7f29f3c..c7be25aa4 100644 --- a/content/docs/addons-shallow-renderer.md +++ b/content/docs/addons-shallow-renderer.md @@ -1,23 +1,23 @@ --- id: shallow-renderer -title: Shallow Renderer +title: 얕은 렌더러 permalink: docs/shallow-renderer.html layout: docs category: Reference --- -**Importing** +**불러오기** ```javascript import ShallowRenderer from 'react-test-renderer/shallow'; // ES6 -var ShallowRenderer = require('react-test-renderer/shallow'); // ES5 with npm +var ShallowRenderer = require('react-test-renderer/shallow'); // npm에서 ES5를 사용하는 경우 ``` -## Overview {#overview} +## 개요 {#overview} -When writing unit tests for React, shallow rendering can be helpful. Shallow rendering lets you render a component "one level deep" and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM. +React를 위한 유닛 테스트를 작성할 때 얕은 렌더링이 유용할 수 있습니다. 얕은 렌더링은 컴포넌트를 "한 단계 깊이"로 렌더링할 수 있으며 인스턴스화 또는 렌더링 되지 않는 자식 컴포넌트의 동작에 대해 걱정 없이 렌더링 메소드가 무엇을 반환하는지에 대해 검증할 수 있습니다. 이 작업은 DOM이 필요하지 않습니다. -For example, if you have the following component: +예를 들어 다음 컴포넌트가 있는 경우 ```javascript function MyComponent() { @@ -30,7 +30,7 @@ function MyComponent() { } ``` -Then you can assert: +다음과 같이 검증할 수 있습니다. ```javascript import ShallowRenderer from 'react-test-renderer/shallow'; @@ -47,22 +47,22 @@ expect(result.props.children).toEqual([ ]); ``` -Shallow testing currently has some limitations, namely not supporting refs. +얕은 테스팅은 현재 몇 가지 제한 사항이 있습니다. 다시 말해 refs를 지원하지 않습니다. -> Note: +> 주의 > -> We also recommend checking out Enzyme's [Shallow Rendering API](https://airbnb.io/enzyme/docs/api/shallow.html). It provides a nicer higher-level API over the same functionality. +> 우리는 또한 Enzyme의 [Shallow Rendering API](https://airbnb.io/enzyme/docs/api/shallow.html)를 확인해 볼 것을 권장합니다. 같은 기능에 대해 더 높은 수준의 API를 제공합니다. -## Reference {#reference} +## 참조 {#reference} ### `shallowRenderer.render()` {#shallowrendererrender} -You can think of the shallowRenderer as a "place" to render the component you're testing, and from which you can extract the component's output. +shallowRenderer는 테스트 중인 컴포넌트를 렌더링하는 "장소(place)"로 생각할 수 있으며 이것으로부터 컴포넌트의 출력을 추출할 수 있습니다. -`shallowRenderer.render()` is similar to [`ReactDOM.render()`](/docs/react-dom.html#render) but it doesn't require DOM and only renders a single level deep. This means you can test components isolated from how their children are implemented. +`shallowRenderer.render()`는 [`ReactDOM.render()`](/docs/react-dom.html#render)와 비슷하지만 DOM을 요구하지 않으며 오직 한 단계 깊이만을 렌더링합니다. 이것은 컴포넌트의 자식들이 어떻게 구현되었는지 신경 쓰지 않고 독립적으로 테스트할 수 있음을 의미합니다. ### `shallowRenderer.getRenderOutput()` {#shallowrenderergetrenderoutput} -After `shallowRenderer.render()` has been called, you can use `shallowRenderer.getRenderOutput()` to get the shallowly rendered output. +`shallowRenderer.render()`가 호출된 후 `shallowRenderer.getRenderOutput()`을 사용하여 얕게 렌더링 된 출력을 얻을 수 있습니다. -You can then begin to assert facts about the output. +그러면 출력에 대해 검증을 시작할 수 있습니다. diff --git a/content/docs/addons-test-utils.md b/content/docs/addons-test-utils.md index a6e06e1be..0f6c8357b 100644 --- a/content/docs/addons-test-utils.md +++ b/content/docs/addons-test-utils.md @@ -1,6 +1,6 @@ --- id: test-utils -title: Test Utilities +title: 테스팅 도구 permalink: docs/test-utils.html layout: docs category: Reference @@ -10,18 +10,18 @@ category: Reference ```javascript import ReactTestUtils from 'react-dom/test-utils'; // ES6 -var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm +var ReactTestUtils = require('react-dom/test-utils'); // npm과 ES5 ``` -## Overview {#overview} +## 개요 {#overview} -`ReactTestUtils` makes it easy to test React components in the testing framework of your choice. At Facebook we use [Jest](https://facebook.github.io/jest/) for painless JavaScript testing. Learn how to get started with Jest through the Jest website's [React Tutorial](https://jestjs.io/docs/tutorial-react). +`ReactTestUtils`는 여러분이 선택한 테스팅 프레임워크에서 테스트를 쉽게 진행할 수 있도록 해 줍니다. Facebook에서는 [Jest](https://facebook.github.io/jest/)를 이용해 더욱 쉽게 JavaScript 테스트를 하고 있습니다. Jest 웹사이트의 [React 자습서](https://jestjs.io/docs/tutorial-react) 문서를 통해 Jest를 시작하는 방법에 대해서 알아보세요. -> Note: +> 주의 > -> We recommend using [`react-testing-library`](https://git.io/react-testing-library) which is designed to enable and encourage writing tests that use your components as the end users do. +> Facebook에서는 [`react-testing-library`](https://git.io/react-testing-library) 사용을 권장합니다. 이 라이브러리는 사용자가 컴포넌트를 사용하는 것처럼 테스트를 작성할 수 있도록 설계되었습니다. > -> Alternatively, Airbnb has released a testing utility called [Enzyme](https://airbnb.io/enzyme/), which makes it easy to assert, manipulate, and traverse your React Components' output. +> 대안으로는 Airbnb에서 출시한 테스팅 도구인 [Enzyme](https://airbnb.io/enzyme/)이 있습니다. Enzyme은 React 컴포넌트의 출력을 쉽게 검증하고 조작하고 탐색할 수 있게 해줍니다. - [`act()`](#act) - [`mockComponent()`](#mockcomponent) @@ -40,20 +40,21 @@ var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm - [`renderIntoDocument()`](#renderintodocument) - [`Simulate`](#simulate) -## Reference {#reference} +## 참조사항 {#reference} ### `act()` {#act} -To prepare a component for assertions, wrap the code rendering it and performing updates inside an `act()` call. This makes your test run closer to how React works in the browser. +컴포넌트의 진단을 준비하기 위해서는 컴포넌트를 렌더링하고 갱신해주는 코드를 `act()`를 호출한 것의 안에 넣어줘야 합니다. 이를 통해 React를 브라우저 내에서 동작하는 것과 비슷한 환경에서 테스트할 수 있습니다. ->Note +>주의 > ->If you use `react-test-renderer`, it also provides an `act` export that behaves the same way. +>`react-test-renderer`를 사용한다면, 똑같이 작동하는 `act` export가 제공됩니다. + +예를 들어, 다음과 같은 `Counter` 컴포넌트가 있다고 해봅시다. -For example, let's say we have this `Counter` component: ```js -class App extends React.Component { +class Counter extends React.Component { constructor(props) { super(props); this.state = {count: 0}; @@ -83,7 +84,7 @@ class App extends React.Component { } ``` -Here is how we can test it: +이런 방식으로 테스트 할 수 있습니다. ```js{3,20-22,29-31} import React from 'react'; @@ -104,7 +105,7 @@ afterEach(() => { }); it('can render and update a counter', () => { - // Test first render and componentDidMount + // 첫 render와 componentDidMount를 테스트 act(() => { ReactDOM.render(, container); }); @@ -113,7 +114,7 @@ it('can render and update a counter', () => { expect(label.textContent).toBe('You clicked 0 times'); expect(document.title).toBe('You clicked 0 times'); - // Test second render and componentDidUpdate + // 두 번째 render와 componentDidUpdate를 테스트 act(() => { button.dispatchEvent(new MouseEvent('click', {bubbles: true})); }); @@ -122,7 +123,7 @@ it('can render and update a counter', () => { }); ``` -Don't forget that dispatching DOM events only works when the DOM container is added to the `document`. You can use a helper like [`react-testing-library`](https://github.com/kentcdodds/react-testing-library) to reduce the boilerplate code. +DOM 이벤트를 붙이는 것은 DOM 컨테이너가 `document` 객체에 추가되었을 때에만 가능하다는 것을 기억하십시오. 불필요하게 반복 되는 코드를 줄이기 위해서 [`react-testing-library`](https://github.com/kentcdodds/react-testing-library)와 같은 것들을 사용할 수 있습니다. * * * @@ -135,11 +136,12 @@ mockComponent( ) ``` -Pass a mocked component module to this method to augment it with useful methods that allow it to be used as a dummy React component. Instead of rendering as usual, the component will become a simple `
` (or other tag if `mockTagName` is provided) containing any provided children. +모의 컴포넌트 모듈을 이 메서드에 넘겨 유용한 메서드들을 붙여 증강해 더미 리액트 컴포넌트로 사용할 수 있습니다. 보통의 경우처럼 렌더링 하지 않고 그 대신 컴포넌트는 간단하게 `
` 태그가 됩니다. `mockTagName`값을 넘겨준다면 `
`대신 다른 태그로 만들어 줄 수 있습니다. + -> Note: +> 주의 > -> `mockComponent()` is a legacy API. We recommend using [shallow rendering](/docs/shallow-renderer.html) or [`jest.mock()`](https://facebook.github.io/jest/docs/en/tutorial-react-native.html#mock-native-modules-using-jestmock) instead. +> `mockComponent()`는 더이상 쓰이지 않는 API입니다. 저희는 [얕은 복사](/docs/shallow-renderer.html) 혹은 [`jest.mock()`](https://facebook.github.io/jest/docs/en/tutorial-react-native.html#mock-native-modules-using-jestmock)을 사용하는 것을 추천합니다. * * * @@ -149,7 +151,7 @@ Pass a mocked component module to this method to augment it with useful methods isElement(element) ``` -Returns `true` if `element` is any React element. +`element`가 React의 element라면 `true`를 반환합니다. * * * @@ -162,7 +164,7 @@ isElementOfType( ) ``` -Returns `true` if `element` is a React element whose type is of a React `componentClass`. +`element`가 `componentClass` 타입의 React element라면 `true`를 반환합니다. * * * @@ -172,7 +174,7 @@ Returns `true` if `element` is a React element whose type is of a React `compone isDOMComponent(instance) ``` -Returns `true` if `instance` is a DOM component (such as a `
` or ``). +`instance`가 `
`나 ``같은 DOM 컴포넌트라면 `true`를 반환합니다. * * * @@ -182,7 +184,7 @@ Returns `true` if `instance` is a DOM component (such as a `
` or ``). isCompositeComponent(instance) ``` -Returns `true` if `instance` is a user-defined component, such as a class or a function. +`instance`가 클래스나 함수 같이 사용자가 정의한 컴포넌트라면 `true`를 반환합니다. * * * @@ -195,7 +197,7 @@ isCompositeComponentWithType( ) ``` -Returns `true` if `instance` is a component whose type is of a React `componentClass`. +`instance`가 `componentClass` 타입을 가진 컴포넌트라면 `true`를 반환합니다. * * * @@ -208,7 +210,7 @@ findAllInRenderedTree( ) ``` -Traverse all components in `tree` and accumulate all components where `test(component)` is `true`. This is not that useful on its own, but it's used as a primitive for other test utils. +`tree`의 모든 컴포넌트를 탐색하여 `test(component)`가 `true`일 때 모든 컴포넌트를 축적합니다. 이 함수는 그 자체만으로는 유용하지 않지만, 다른 테스트 도구의 기반이 됩니다. * * * @@ -221,7 +223,7 @@ scryRenderedDOMComponentsWithClass( ) ``` -Finds all DOM elements of components in the rendered tree that are DOM components with the class name matching `className`. +렌더링 된 트리에서 조건 `className`에 만족하는 class명을 가지고 있는 DOM 컴포넌트의 DOM 엘리먼트를 모두 검색합니다. * * * @@ -234,7 +236,7 @@ findRenderedDOMComponentWithClass( ) ``` -Like [`scryRenderedDOMComponentsWithClass()`](#scryrendereddomcomponentswithclass) but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one. +[`scryRenderedDOMComponentsWithClass()`](#scryrendereddomcomponentswithclass)와 기능이 유사하나 결과값이 하나라고 가정하고 그 결과값만을 반환합니다. 두 개 이상의 결과값이 있다면 예외를 반환합니다. * * * @@ -247,7 +249,7 @@ scryRenderedDOMComponentsWithTag( ) ``` -Finds all DOM elements of components in the rendered tree that are DOM components with the tag name matching `tagName`. +렌더링 된 트리 내에서 조건 `tagName`에 만족하는 tag명을 가진 DOM 컴포넌트의 DOM 엘리먼트를 모두 검색합니다. * * * @@ -260,7 +262,7 @@ findRenderedDOMComponentWithTag( ) ``` -Like [`scryRenderedDOMComponentsWithTag()`](#scryrendereddomcomponentswithtag) but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one. +[`scryRenderedDOMComponentsWithTag()`](#scryrendereddomcomponentswithtag)와 기능이 유사하나 결과값이 하나라고 가정하고 그 결과값만을 반환합니다. 두 개 이상의 결과값이 있다면 예외를 뱉습니다. * * * @@ -273,7 +275,7 @@ scryRenderedComponentsWithType( ) ``` -Finds all instances of components with type equal to `componentClass`. +`componentClass` 타입을 가진 모든 인스턴스를 검색합니다. * * * @@ -286,7 +288,7 @@ findRenderedComponentWithType( ) ``` -Same as [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype) but expects there to be one result and returns that one result, or throws exception if there is any other number of matches besides one. +[`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype)와 기능이 유사하나 결과값이 하나라고 가정하고 그 결과값만을 반환합니다. 두 개 이상의 결과값이 있다면 예외를 뱉습니다. *** @@ -296,20 +298,20 @@ Same as [`scryRenderedComponentsWithType()`](#scryrenderedcomponentswithtype) bu renderIntoDocument(element) ``` -Render a React element into a detached DOM node in the document. **This function requires a DOM.** It is effectively equivalent to: +React 엘리먼트를 document내의 떨어져 있는 DOM 노드에 렌더링합니다. **이 함수를 쓰려면 DOM이 필요합니다.** 이 함수는 다음 코드와 같은 기능을 합니다. ```js const domContainer = document.createElement('div'); ReactDOM.render(element, domContainer); ``` -> Note: +> 주의 > -> You will need to have `window`, `window.document` and `window.document.createElement` globally available **before** you import `React`. Otherwise React will think it can't access the DOM and methods like `setState` won't work. +> `window`, `window.document`와 `window.document.createElement`는 `React`를 **가져와서 사용하기 전에도** 전역적으로 사용할 수 있습니다. 만약 그렇지 않다면 React는 DOM에 접근할 수 없다고 간주할 것이며 `setState`와 같은 메서드들이 작동하지 않을 것 입니다. * * * -## Other Utilities {#other-utilities} +## 다른 테스팅 도구들 {#other-utilities} ### `Simulate` {#simulate} @@ -320,11 +322,12 @@ Simulate.{eventName}( ) ``` -Simulate an event dispatch on a DOM node with optional `eventData` event data. +이벤트 데이터인 `eventData`를 옵션으로 준 DOM 노드에 붙이는 이벤트를 시뮬레이팅합니다. -`Simulate` has a method for [every event that React understands](/docs/events.html#supported-events). +`Simulate`는 [React가 이해하는 모든 이벤트](/docs/events.html#supported-events)를 위한 메서드를 가집니다. -**Clicking an element** + +**엘리먼트 클릭** ```javascript // @@ -332,7 +335,7 @@ const node = this.button; ReactTestUtils.Simulate.click(node); ``` -**Changing the value of an input field and then pressing ENTER.** +**입력 필드의 값을 바꾼 뒤 ENTER키 누르기** ```javascript // this.textInput = node} /> @@ -342,8 +345,9 @@ ReactTestUtils.Simulate.change(node); ReactTestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13}); ``` -> Note +> 주의 > -> You will have to provide any event property that you're using in your component (e.g. keyCode, which, etc...) as React is not creating any of these for you. +> 컴포넌트 내에서 사용하고 있는 keyCode, which와 같은 이벤트 프로퍼티는 별도로 제공해주어야 합니다. React에서는 이러한 이벤트 프로퍼티를 자동으로 만들어 주지 않습니다. + * * * diff --git a/content/docs/cdn-links.md b/content/docs/cdn-links.md index 73e3e8171..79a4e3632 100644 --- a/content/docs/cdn-links.md +++ b/content/docs/cdn-links.md @@ -1,37 +1,37 @@ --- id: cdn-links -title: CDN Links +title: CDN 링크 permalink: docs/cdn-links.html prev: create-a-new-react-app.html next: hello-world.html --- -Both React and ReactDOM are available over a CDN. +React와 ReactDOM 모두 CDN을 통해 사용할 수 있습니다. ```html ``` -The versions above are only meant for development, and are not suitable for production. Minified and optimized production versions of React are available at: +위의 코드는 개발용으로 적합하며 배포용 버전에는 적합하지 않습니다. React의 용량 및 성능 최적화된 배포용 버전은 아래와 같이 제공되고 있습니다. ```html ``` -To load a specific version of `react` and `react-dom`, replace `16` with the version number. +`react`와 `react-dom`의 특정 버전을 로딩하려면 `16`을 사용하고자 하는 버전 넘버로 대체하면 됩니다. -### Why the `crossorigin` Attribute? {#why-the-crossorigin-attribute} +### `crossorigin` 속성이 필요한 이유 {#why-the-crossorigin-attribute} -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: +CDN을 통해 React를 사용한다면, [`crossorigin`](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) 어트리뷰트(attribute)와 함께 사용하는 것을 권장합니다. ```html ``` -We also recommend to verify that the CDN you are using sets the `Access-Control-Allow-Origin: *` HTTP header: +또한 사용 중인 CDN이 `Access-Control-Allow-Origin: *` HTTP 헤더 설정을 사용하는지 확인하는 것이 좋습니다. ![Access-Control-Allow-Origin: *](../images/docs/cdn-cors-header.png) -This enables a better [error handling experience](/blog/2017/07/26/error-handling-in-react-16.html) in React 16 and later. +이를 통해 React 16 버전과 다음 버전에서 더 쉽게 [에러 처리](/blog/2017/07/26/error-handling-in-react-16.html)를 할 수 있습니다. diff --git a/content/docs/code-splitting.md b/content/docs/code-splitting.md index c0985e92c..49c55f5d8 100644 --- a/content/docs/code-splitting.md +++ b/content/docs/code-splitting.md @@ -1,20 +1,16 @@ --- id: code-splitting -title: Code-Splitting +title: 코드 분할 permalink: docs/code-splitting.html --- -## Bundling {#bundling} +## 번들링 {#bundling} -Most React apps will have their files "bundled" using tools like -[Webpack](https://webpack.js.org/) or [Browserify](http://browserify.org/). -Bundling is the process of following imported files and merging them into a -single file: a "bundle". This bundle can then be included on a webpage to load -an entire app at once. +대부분 React 앱들은 [Webpack](https://webpack.js.org/) 이나 [Browserify](http://browserify.org/) 같은 툴을 사용하여 여러 파일을 하나로 병합한 "번들 된" 파일을 웹 페이지에 포함하여 한 번에 전체 앱을 로드 할 수 있습니다. -#### Example {#example} +#### 예시 {#example} -**App:** +**App** ```js // app.js @@ -30,7 +26,7 @@ export function add(a, b) { } ``` -**Bundle:** +**Bundle** ```js function add(a, b) { @@ -40,44 +36,32 @@ function add(a, b) { console.log(add(16, 26)); // 42 ``` -> Note: +> 주의 > -> Your bundles will end up looking a lot different than this. +> 실제 번들은 위 예시와는 많이 다르게 보일 겁니다. -If you're using [Create React App](https://github.com/facebookincubator/create-react-app), [Next.js](https://github.com/zeit/next.js/), [Gatsby](https://www.gatsbyjs.org/), or a similar tool, you will have a Webpack setup out of the box to bundle your -app. +[Create React App](https://github.com/facebookincubator/create-react-app)이나 [Next.js](https://github.com/zeit/next.js/), [Gatsby](https://www.gatsbyjs.org/) 혹은 비슷한 툴을 사용한다면 여러분이 설치한 앱에서 Webpack을 같이 설치했을 겁니다. -If you aren't, you'll need to setup bundling yourself. For example, see the -[Installation](https://webpack.js.org/guides/installation/) and -[Getting Started](https://webpack.js.org/guides/getting-started/) guides on the -Webpack docs. +이런 툴을 사용하지 않는다면 여러분이 스스로 번들링을 설정해야 합니다. 이 경우 Webpack의 +[설치하기](https://webpack.js.org/guides/installation/) 문서와 +[시작하기](https://webpack.js.org/guides/getting-started/) 문서를 참조해 주세요. -## Code Splitting {#code-splitting} +## 코드 분할 {#code-splitting} -Bundling is great, but as your app grows, your bundle will grow too. Especially -if you are including large third-party libraries. You need to keep an eye on -the code you are including in your bundle so that you don't accidentally make -it so large that your app takes a long time to load. +번들링은 훌륭하지만 여러분의 앱이 커지면 번들도 커집니다. 특히 큰 규모의 서드 파티 라이브러리를 추가할 때 실수로 앱이 커져서 로드 시간이 길어지는 것을 방지하기 위해 코드를 주의 깊게 살펴야 합니다. -To avoid winding up with a large bundle, it's good to get ahead of the problem -and start "splitting" your bundle. - [Code-Splitting](https://webpack.js.org/guides/code-splitting/) is a feature -supported by bundlers like Webpack and Browserify (via -[factor-bundle](https://github.com/browserify/factor-bundle)) which can create -multiple bundles that can be dynamically loaded at runtime. +번들이 거대해지는 것을 방지하기 위한 좋은 해결방법은 번들을 "나누는" 것입니다. +[코드 분할](https://webpack.js.org/guides/code-splitting/)은 런타임시 여러 번들을 동적으로 만들고 불러오는 것으로 Webpack 와 Browserify ([factor-bundle](https://github.com/browserify/factor-bundle)) 같은 번들러들이 지원하는 기능입니다. -Code-splitting your app can help you "lazy-load" just the things that are -currently needed by the user, which can dramatically improve the performance of -your app. While you haven't reduced the overall amount of code in your app, -you've avoided loading code that the user may never need, and reduced the amount -of code needed during the initial load. + +코드 분할은 여러분의 앱을 "지연 로딩" 하게 도와주고 앱 사용자에게 획기적인 성능 향상을 하게 합니다. +앱의 코드 양을 줄이지 않고도 사용자가 필요하지 않은 코드를 불러오지 않게 하며 앱의 초기화 로딩에 필요한 비용을 줄여줍니다. ## `import()` {#import} -The best way to introduce code-splitting into your app is through the dynamic -`import()` syntax. + 앱에 코드 분할을 도입하는 가장 좋은 방법은 동적 `import()` 문법을 사용하는 방법입니다. -**Before:** +**Before** ```js import { add } from './math'; @@ -85,7 +69,7 @@ import { add } from './math'; console.log(add(16, 26)); ``` -**After:** +**After** ```js import("./math").then(math => { @@ -93,33 +77,30 @@ import("./math").then(math => { }); ``` -> Note: +> 주의 > -> The dynamic `import()` syntax is a ECMAScript (JavaScript) -> [proposal](https://github.com/tc39/proposal-dynamic-import) not currently -> part of the language standard. It is expected to be accepted in the -> near future. +> 동적 `import()` 문법은 아직 ECMAScript (JavaScript)의 표준 문법이 아니라 +> [제안](https://github.com/tc39/proposal-dynamic-import)입니다. +> 동적 `import()`은 가까운 미래에 표준에 추가될 것으로 보입니다. -When Webpack comes across this syntax, it automatically starts code-splitting -your app. If you're using Create React App, this is already configured for you -and you can [start using it](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting) immediately. It's also supported -out of the box in [Next.js](https://github.com/zeit/next.js/#dynamic-import). +Webpack이 이 구문을 만나게 되면 앱의 코드를 분할합니다. +Create React App을 사용하고 있다면 이미 Webpack이 구성이 되어 있기 때문에 즉시 [사용](https://facebook.github.io/create-react-app/docs/code-splitting)할 수 있습니다. +[Next.js](https://github.com/zeit/next.js/#dynamic-import) 역시 지원합니다. -If you're setting up Webpack yourself, you'll probably want to read Webpack's -[guide on code splitting](https://webpack.js.org/guides/code-splitting/). Your Webpack config should look vaguely [like this](https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269). +스스로 Webpack을 구성하고자 한다면 Webpack의 +[코드 분할 가이드](https://webpack.js.org/guides/code-splitting/)를 참조하세요. Webpack 설정은 [가이드](https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269)에 있습니다. -When using [Babel](https://babeljs.io/), you'll need to make sure that Babel can -parse the dynamic import syntax but is not transforming it. For that you will need [babel-plugin-syntax-dynamic-import](https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import). +[Babel](http://babeljs.io/)을 사용할 때는 Babel이 동적 import를 인식할 수 있지만 변환하지는 않도록 합니다. 이를 위해 [babel-plugin-syntax-dynamic-import](https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import)를 사용하세요. ## `React.lazy` {#reactlazy} -> Note: +> 주의 > -> `React.lazy` and Suspense is not yet available for server-side rendering. If you want to do code-splitting in a server rendered app, we recommend [Loadable Components](https://github.com/smooth-code/loadable-components). It has a nice [guide for bundle splitting with server-side rendering](https://github.com/smooth-code/loadable-components/blob/master/packages/server/README.md). +> `React.lazy`와 Suspense는 아직 서버 사이드 렌더링을 할 수 없습니다. 서버에서 렌더링 된 앱에서 코드 분할을 하기 원한다면 [Loadable Components](https://github.com/smooth-code/loadable-components)를 추천합니다. 이는 [서버 사이드 렌더링과 번들 스플리팅에 대한 좋은 가이드](https://github.com/smooth-code/loadable-components/blob/master/packages/server/README.md)입니다. -The `React.lazy` function lets you render a dynamic import as a regular component. +`React.lazy` 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다. -**Before:** +**Before** ```js import OtherComponent from './OtherComponent'; @@ -133,7 +114,7 @@ function MyComponent() { } ``` -**After:** +**After** ```js const OtherComponent = React.lazy(() => import('./OtherComponent')); @@ -146,14 +127,14 @@ function MyComponent() { ); } ``` +`MyComponent`가 렌더링 될 때 `OtherComponent`를 포함한 번들을 자동으로 불러옵니다. -This will automatically load the bundle containing the `OtherComponent` when this component gets rendered. - -`React.lazy` takes a function that must call a dynamic `import()`. This must return a `Promise` which resolves to a module with a `default` export containing a React component. +`React.lazy`는 동적 `import()`를 호출하는 함수를 인자로 가집니다. 이 함수는 React 컴포넌트를 +포함하며 `default` export를 가진 모듈로 결정되는 `Promise`로 반환해야 합니다. ### Suspense {#suspense} -If the module containing the `OtherComponent` is not yet loaded by the time `MyComponent` renders, we must show some fallback content while we're waiting for it to load - such as a loading indicator. This is done using the `Suspense` component. +`MyComponent`를 렌더링할 때 `OtherComponent`를 포함하는 모듈이 아직 로드되지 않았다면, 로드를 기다리는 동안 로딩처럼 예비 컨텐츠를 보여줘야 합니다. 이는 `Suspense` 컴포넌트를 사용하여 처리할 수 있습니다. ```js const OtherComponent = React.lazy(() => import('./OtherComponent')); @@ -169,7 +150,8 @@ function MyComponent() { } ``` -The `fallback` prop accepts any React elements that you want to render while waiting for the component to load. You can place the `Suspense` component anywhere above the lazy component. You can even wrap multiple lazy components with a single `Suspense` component. +`fallback` prop은 컴포넌트가 로드될 때까지 기다리는 동안 렌더링하려는 React 엘리먼트를 받아들입니다. `Suspense` 컴포넌트는 lazy 컴포넌트를 감쌉니다. 하나의 `Suspense` 컴포넌트로 여러 lazy 컴포넌트를 감쌀 수도 있습니다. + ```js const OtherComponent = React.lazy(() => import('./OtherComponent')); @@ -190,8 +172,8 @@ function MyComponent() { ``` ### Error boundaries {#error-boundaries} - -If the other module fails to load (for example, due to network failure), it will trigger an error. You can handle these errors to show a nice user experience and manage recovery with [Error Boundaries](/docs/error-boundaries.html). Once you've created your Error Boundary, you can use it anywhere above your lazy components to display an error state when there's a network error. +네트워크 장애 같은 이유로 다른 모듈을 로드에 실패할 경우 에러를 발생시킬 수 있습니다. 이때 [Error Boundaries](/docs/error-boundaries.html)를 이용하여 사용자의 경험과 복구 관리를 처리할 수 있습니다. +Error Boundary를 만들고 lazy 컴포넌트를 감싸면 네트워크 장애가 발생했을 때 에러를 표시할 수 있습니다. ```js import MyErrorBoundary from './MyErrorBoundary'; @@ -214,17 +196,13 @@ const MyComponent = () => ( ## Route-based code splitting {#route-based-code-splitting} -Deciding where in your app to introduce code splitting can be a bit tricky. You -want to make sure you choose places that will split bundles evenly, but won't -disrupt the user experience. +앱에 코드 분할을 어느 곳에 도입할지 결정하는 것은 조금 까다롭습니다. +여러분은 사용자의 경험을 헤치지 않으면서 번들을 균등하게 분배할 곳을 찾고자 합니다. -A good place to start is with routes. Most people on the web are used to -page transitions taking some amount of time to load. You also tend to be -re-rendering the entire page at once so your users are unlikely to be -interacting with other elements on the page at the same time. +이를 시작하기 좋은 장소는 라우트입니다. 웹 페이지를 불러오는 시간은 페이지 전환에 어느 정도 발생하며 대부분 페이지를 한번에 렌더링하기 때문에 +사용자가 페이지를 렌더링하는 동안 다른 요소와 상호작용하지 않습니다. -Here's an example of how to setup route-based code splitting into your app using -libraries like [React Router](https://reacttraining.com/react-router/) with `React.lazy`. +`React.lazy`를 [React Router](https://reacttraining.com/react-router/) 라이브러리를 사용해서 애플리케이션에 라우트 기반 코드 분할을 설정하는 예시입니다. ```js import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; @@ -247,7 +225,7 @@ const App = () => ( ## Named Exports {#named-exports} -`React.lazy` currently only supports default exports. If the module you want to import uses named exports, you can create an intermediate module that reexports it as the default. This ensures that treeshaking keeps working and that you don't pull in unused components. +`React.lazy`는 현재 default exports만 지원합니다. named exports를 사용하고자 한다면 default로 이름을 재정의한 중간 모듈을 생성할 수 있습니다. 이렇게 하면 treeshaking이 계속 동작하고 사용하지 않는 컴포넌트는 가져오지 않습니다. ```js // ManyComponents.js diff --git a/content/docs/components-and-props.md b/content/docs/components-and-props.md index 4b3bbb6e6..f9eec02ec 100644 --- a/content/docs/components-and-props.md +++ b/content/docs/components-and-props.md @@ -16,13 +16,13 @@ prev: rendering-elements.html next: state-and-lifecycle.html --- -Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components. You can find a [detailed component API reference here](/docs/react-component.html). +컴포넌트를 통해 UI를 재사용 가능한 개별적인 여러 조각으로 나누고, 각 조각을 개별적으로 살펴볼 수 있습니다. 이 페이지에서는 컴포넌트의 개념을 소개합니다. [자세한 컴포넌트 API 레퍼런스는 여기](/docs/react-component.html)에서 확인할 수 있습니다. -Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen. +개념적으로 컴포넌트는 JavaScript 함수와 유사합니다. "props"라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환합니다. -## Function and Class Components {#function-and-class-components} +## 함수 컴포넌트와 클래스 컴포넌트 {#function-and-class-components} -The simplest way to define a component is to write a JavaScript function: +컴포넌트를 정의하는 가장 간단한 방법은 JavaScript 함수를 작성하는 것입니다. ```js function Welcome(props) { @@ -30,9 +30,9 @@ function Welcome(props) { } ``` -This function is a valid React component because it accepts a single "props" (which stands for properties) object argument with data and returns a React element. We call such components "function components" because they are literally JavaScript functions. +이 함수는 데이터를 가진 하나의 "props" (props는 속성을 나타내는 데이터입니다) 객체 인자를 받은 후 React 엘리먼트를 반환하므로 유효한 React 컴포넌트입니다. 이러한 컴포넌트는 JavaScript 함수이기 때문에 말 그대로 "함수 컴포넌트"라고 호칭합니다. -You can also use an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) to define a component: +또한 [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes)를 사용하여 컴포넌트를 정의할 수 있습니다. ```js class Welcome extends React.Component { @@ -42,27 +42,27 @@ class Welcome extends React.Component { } ``` -The above two components are equivalent from React's point of view. +React의 관점에서 볼 때 위 두 가지 유형의 컴포넌트는 동일합니다. -Classes have some additional features that we will discuss in the [next sections](/docs/state-and-lifecycle.html). Until then, we will use function components for their conciseness. +class는 몇 가지 추가 기능이 있으며 이에 대해서는 [다음 장](/docs/state-and-lifecycle.html)에서 설명합니다. 그때까지는 간결성을 위해 함수 컴포넌트를 사용하겠습니다. -## Rendering a Component {#rendering-a-component} +## 컴포넌트 렌더링 {#rendering-a-component} -Previously, we only encountered React elements that represent DOM tags: +이전까지는 React 엘리먼트를 DOM 태그로 나타냈습니다. ```js const element =
; ``` -However, elements can also represent user-defined components: +React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있습니다. ```js const element = ; ``` -When React sees an element representing a user-defined component, it passes JSX attributes to this component as a single object. We call this object "props". +React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트를 해당 컴포넌트에 단일 객체로 전달합니다. 이 객체를 "props"라고 합니다. -For example, this code renders "Hello, Sara" on the page: +다음은 페이지에 "Hello, Sara"를 렌더링하는 예시입니다. ```js{1,5} function Welcome(props) { @@ -76,26 +76,29 @@ ReactDOM.render( ); ``` -[](codepen://components-and-props/rendering-a-component) +[CodePen에서 시험해보기](codepen://components-and-props/rendering-a-component) -Let's recap what happens in this example: +이 예시에서는 다음과 같은 일들이 일어납니다. -1. We call `ReactDOM.render()` with the `` element. -2. React calls the `Welcome` component with `{name: 'Sara'}` as the props. -3. Our `Welcome` component returns a `

Hello, Sara

` element as the result. -4. React DOM efficiently updates the DOM to match `

Hello, Sara

`. +1. `` 엘리먼트로 `ReactDOM.render()`를 호출합니다. +2. React는 `{name: 'Sara'}`를 props로 하여 `Welcome` 컴포넌트를 호출합니다. +3. `Welcome` 컴포넌트는 결과적으로 `

Hello, Sara

` 엘리먼트를 반환합니다. +4. React DOM은 `

Hello, Sara

` 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트합니다. ->**Note:** Always start component names with a capital letter. + + +>**주의: 컴포넌트의 이름은 항상 대문자로 시작합니다.** > ->React treats components starting with lowercase letters as DOM tags. For example, `
` represents an HTML div tag, but `` represents a component and requires `Welcome` to be in scope. +>React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리합니다. 예를 들어 `
`는 HTML div 태그를 나타내지만, ``은 컴포넌트를 나타내며 범위 안에 `Welcome`이 있어야 합니다. > ->To learn more about the reasoning behind this convention, please read [JSX In Depth](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized). +>이 규칙에 대한 자세한 내용은 [여기](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized)에서 확인할 수 있습니다. + -## Composing Components {#composing-components} +## 컴포넌트 합성 {#composing-components} -Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components. +컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있습니다. 이는 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음을 의미합니다. React 앱에서는 버튼, 폼, 다이얼로그, 화면 등의 모든 것들이 흔히 컴포넌트로 표현됩니다. -For example, we can create an `App` component that renders `Welcome` many times: +예를 들어 `Welcome`을 여러 번 렌더링하는 `App` 컴포넌트를 만들 수 있습니다. ```js{8-10} function Welcome(props) { @@ -118,15 +121,15 @@ ReactDOM.render( ); ``` -[](codepen://components-and-props/composing-components) +[CodePen에서 시험해보기](codepen://components-and-props/composing-components) -Typically, new React apps have a single `App` component at the very top. However, if you integrate React into an existing app, you might start bottom-up with a small component like `Button` and gradually work your way to the top of the view hierarchy. +일반적으로 새 React 앱은 최상위에 단일 `App` 컴포넌트를 가지고 있습니다. 하지만 기존 앱에 React를 통합하는 경우에는 `Button`과 같은 작은 컴포넌트부터 시작해서 뷰 계층의 상단으로 올라가면서 점진적으로 작업해야 할 수 있습니다. -## Extracting Components {#extracting-components} +## 컴포넌트 추출 {#extracting-components} -Don't be afraid to split components into smaller components. +컴포넌트를 여러 개의 작은 컴포넌트로 나누는 것을 두려워하지 마세요. -For example, consider this `Comment` component: +다음 `Comment` 컴포넌트를 살펴봅시다. ```js function Comment(props) { @@ -152,13 +155,13 @@ function Comment(props) { } ``` -[](codepen://components-and-props/extracting-components) +[CodePen에서 시험해보기](codepen://components-and-props/extracting-components) -It accepts `author` (an object), `text` (a string), and `date` (a date) as props, and describes a comment on a social media website. +이 컴포넌트는 `author`(객체), `text`(문자열) 및 `date`(날짜)를 props로 받은 후 소셜 미디어 웹 사이트의 코멘트를 나타냅니다. -This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let's extract a few components from it. +이 컴포넌트는 구성요소들이 모두 중첩 구조로 이루어져 있어서 변경하기 어려울 수 있으며, 각 구성요소를 개별적으로 재사용하기도 힘듭니다. 이 컴포넌트에서 몇 가지 컴포넌트를 추출하겠습니다. -First, we will extract `Avatar`: +먼저 `Avatar`를 추출하겠습니다. ```js{3-6} function Avatar(props) { @@ -171,11 +174,11 @@ function Avatar(props) { } ``` -The `Avatar` doesn't need to know that it is being rendered inside a `Comment`. This is why we have given its prop a more generic name: `user` rather than `author`. +`Avatar` 는 자신이 `Comment` 내에서 렌더링 된다는 것을 알 필요가 없습니다. 따라서 props의 이름을 `author`에서 더욱 일반화된 `user`로 변경하였습니다. -We recommend naming props from the component's own point of view rather than the context in which it is being used. +props의 이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓는 것을 권장합니다. -We can now simplify `Comment` a tiny bit: +이제 `Comment` 가 살짝 단순해졌습니다. ```js{5} function Comment(props) { @@ -198,7 +201,7 @@ function Comment(props) { } ``` -Next, we will extract a `UserInfo` component that renders an `Avatar` next to the user's name: +다음으로 `Avatar` 옆에 사용자의 이름을 렌더링하는 `UserInfo` 컴포넌트를 추출하겠습니다. ```js{3-8} function UserInfo(props) { @@ -213,7 +216,7 @@ function UserInfo(props) { } ``` -This lets us simplify `Comment` even further: +`Comment` 가 더욱 단순해졌습니다. ```js{4} function Comment(props) { @@ -231,13 +234,13 @@ function Comment(props) { } ``` -[](codepen://components-and-props/extracting-components-continued) +[CodePen에서 시험해보기](codepen://components-and-props/extracting-components-continued) -Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (`Button`, `Panel`, `Avatar`), or is complex enough on its own (`App`, `FeedStory`, `Comment`), it is a good candidate to be a reusable component. +처음에는 컴포넌트를 추출하는 작업이 지루해 보일 수 있습니다. 하지만 재사용 가능한 컴포넌트를 만들어 놓는 것은 더 큰 앱에서 작업할 때 두각을 나타냅니다. UI 일부가 여러 번 사용되거나 (`Button`, `Panel`, `Avatar`), UI 일부가 자체적으로 복잡한 (`App`, `FeedStory`, `Comment`) 경우에는 재사용 가능한 컴포넌트로 만드는 것이 좋습니다. -## Props are Read-Only {#props-are-read-only} +## props는 읽기 전용입니다. {#props-are-read-only} -Whether you declare a component [as a function or a class](#function-and-class-components), it must never modify its own props. Consider this `sum` function: +함수 컴포넌트나 클래스 컴포넌트 모두 컴포넌트의 자체 props를 수정해서는 안 됩니다. 다음 `sum` 함수를 살펴봅시다. ```js function sum(a, b) { @@ -245,9 +248,9 @@ function sum(a, b) { } ``` -Such functions are called ["pure"](https://en.wikipedia.org/wiki/Pure_function) because they do not attempt to change their inputs, and always return the same result for the same inputs. +이런 함수들은 [순수 함수](https://en.wikipedia.org/wiki/Pure_function)라고 호칭합니다. 입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문입니다. -In contrast, this function is impure because it changes its own input: +반면에 다음 함수는 자신의 입력값을 변경하기 때문에 순수 함수가 아닙니다. ```js function withdraw(account, amount) { @@ -255,8 +258,8 @@ function withdraw(account, amount) { } ``` -React is pretty flexible but it has a single strict rule: +React는 매우 유연하지만 한 가지 엄격한 규칙이 있습니다. -**All React components must act like pure functions with respect to their props.** +**모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 합니다.** -Of course, application UIs are dynamic and change over time. In the [next section](/docs/state-and-lifecycle.html), we will introduce a new concept of "state". State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule. +물론 애플리케이션 UI는 동적이며 시간에 따라 변합니다. [다음 장](/docs/state-and-lifecycle.html)에서는 "state"라는 새로운 개념을 소개합니다. React 컴포넌트는 state를 통해 위 규칙을 위반하지 않고 사용자 액션, 네트워크 응답 및 다른 요소에 대한 응답으로 시간에 따라 자신의 출력값을 변경할 수 있습니다. \ No newline at end of file diff --git a/content/docs/composition-vs-inheritance.md b/content/docs/composition-vs-inheritance.md index c86735ef7..24020ca35 100644 --- a/content/docs/composition-vs-inheritance.md +++ b/content/docs/composition-vs-inheritance.md @@ -1,6 +1,6 @@ --- id: composition-vs-inheritance -title: Composition vs Inheritance +title: 합성 (Composition) vs 상속 (Inheritance) permalink: docs/composition-vs-inheritance.html redirect_from: - "docs/multiple-components.html" @@ -8,15 +8,15 @@ prev: lifting-state-up.html next: thinking-in-react.html --- -React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components. +React는 강력한 합성 모델을 가지고 있으며, 상속 대신 합성을 사용하여 컴포넌트 간에 코드를 재사용하는 것이 좋습니다. -In this section, we will consider a few problems where developers new to React often reach for inheritance, and show how we can solve them with composition. +이번 문서에서는 React를 처음 접한 개발자들이 종종 상속으로 인해 부딪히는 몇 가지 문제들과 합성을 통해 이러한 문제를 해결하는 방법을 살펴볼 것입니다. -## Containment {#containment} +## 컴포넌트에서 다른 컴포넌트를 담기 {#containment} -Some components don't know their children ahead of time. This is especially common for components like `Sidebar` or `Dialog` that represent generic "boxes". +어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올 지 미리 예상할 수 없는 경우가 있습니다. 범용적인 '박스' 역할을 하는 `Sidebar` 혹은 `Dialog`와 같은 컴포넌트에서 특히 자주 볼 수 있습니다. -We recommend that such components use the special `children` prop to pass children elements directly into their output: +이러한 컴포넌트에서는 특수한 `children` prop을 사용하여 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋습니다. ```js{4} function FancyBorder(props) { @@ -28,7 +28,7 @@ function FancyBorder(props) { } ``` -This lets other components pass arbitrary children to them by nesting the JSX: +이러한 방식으로 다른 컴포넌트에서 JSX를 중첩하여 임의의 자식을 전달할 수 있습니다. ```js{4-9} function WelcomeDialog() { @@ -45,11 +45,11 @@ function WelcomeDialog() { } ``` -**[Try it on CodePen](https://codepen.io/gaearon/pen/ozqNOV?editors=0010)** +**[CodePen에서 실행하기](https://codepen.io/gaearon/pen/ozqNOV?editors=0010)** -Anything inside the `` JSX tag gets passed into the `FancyBorder` component as a `children` prop. Since `FancyBorder` renders `{props.children}` inside a `
`, the passed elements appear in the final output. +`` JSX 태그 안에 있는 것들이 `FancyBorder` 컴포넌트의 `children` prop으로 전달됩니다. `FancyBorder`는 `{props.children}`을 `
` 안에 렌더링하므로 전달된 엘리먼트들이 최종 출력됩니다. -While this is less common, sometimes you might need multiple "holes" in a component. In such cases you may come up with your own convention instead of using `children`: +흔하진 않지만 종종 컴포넌트에 여러 개의 "구멍"이 필요할 수도 있습니다. 이런 경우에는 `children` 대신 자신만의 고유한 방식을 적용할 수도 있습니다. ```js{5,8,18,21} function SplitPane(props) { @@ -78,15 +78,15 @@ function App() { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZOJp?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/gwZOJp?editors=0010) -React elements like `` and `` are just objects, so you can pass them as props like any other data. This approach may remind you of "slots" in other libraries but there are no limitations on what you can pass as props in React. +``와 ``같은 React 엘리먼트는 단지 객체이기 때문에 다른 데이터처럼 prop으로 전달할 수 있습니다. 이러한 접근은 다른 라이브러리의 "슬롯 (slots)"과 비슷해보이지만 React에서 prop으로 전달할 수 있는 것에는 제한이 없습니다. -## Specialization {#specialization} +## 특수화 {#specialization} -Sometimes we think about components as being "special cases" of other components. For example, we might say that a `WelcomeDialog` is a special case of `Dialog`. +때로는 어떤 컴포넌트의 "특수한 경우"인 컴포넌트를 고려해야 하는 경우가 있습니다. 예를 들어, `WelcomeDialog`는 `Dialog`의 특수한 경우라고 할 수 있습니다. -In React, this is also achieved by composition, where a more "specific" component renders a more "generic" one and configures it with props: +React에서는 이 역시 합성을 통해 해결할 수 있습니다. 더 "구체적인" 컴포넌트가 "일반적인" 컴포넌트를 렌더링하고 props를 통해 내용을 구성합니다. ```js{5,8,16-18} function Dialog(props) { @@ -111,9 +111,9 @@ function WelcomeDialog() { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/kkEaOZ?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/kkEaOZ?editors=0010) -Composition works equally well for components defined as classes: +합성은 클래스로 정의된 컴포넌트에서도 동일하게 적용됩니다. ```js{10,27-31} function Dialog(props) { @@ -161,12 +161,12 @@ class SignUpDialog extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZbYa?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/gwZbYa?editors=0010) -## So What About Inheritance? {#so-what-about-inheritance} +## 그렇다면 상속은? {#so-what-about-inheritance} -At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies. +Facebook에서는 수천 개의 React 컴포넌트를 사용하지만, 컴포넌트를 상속 계층 구조로 작성을 권장할만한 사례를 아직 찾지 못했습니다. -Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions. +props와 합성은 명시적이고 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징하는데 필요한 모든 유연성을 제공합니다. 컴포넌트가 원시 타입의 값, React 엘리먼트 혹은 함수 등 어떠한 props도 받을 수 있다는 것을 기억하세요. -If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it. +UI가 아닌 기능을 여러 컴포넌트에서 재사용하기를 원한다면, 별도의 JavaScript 모듈로 분리하는 것이 좋습니다. 컴포넌트에서 해당 함수, 객체, 클래스 등을 import 하여 사용할 수 있습니다. 상속받을 필요 없이 말이죠. \ No newline at end of file diff --git a/content/docs/conditional-rendering.md b/content/docs/conditional-rendering.md index 7df19bb98..5e979e22d 100644 --- a/content/docs/conditional-rendering.md +++ b/content/docs/conditional-rendering.md @@ -1,6 +1,6 @@ --- id: conditional-rendering -title: Conditional Rendering +title: 조건부 렌더링 permalink: docs/conditional-rendering.html prev: handling-events.html next: lists-and-keys.html @@ -8,11 +8,11 @@ redirect_from: - "tips/false-in-jsx.html" --- -In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application. +React에서는 원하는 동작을 캡슐화하는 컴포넌트를 만들 수 있습니다. 이렇게 하면 애플리케이션의 상태에 따라서 컴포넌트 중 몇 개만을 렌더링할 수 있습니다. -Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like [`if`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) or the [conditional operator](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) to create elements representing the current state, and let React update the UI to match them. +React에서 조건부 렌더링은 JavaScript에서의 조건 처리와 같이 동작합니다. [`if`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/if...else) 나 [`조건부 연산자`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) 와 같은 JavaScript 연산자를 현재 상태를 나타내는 엘리먼트를 만드는 데에 사용하세요. 그러면 React는 현재 상태에 맞게 UI를 업데이트할 것입니다. -Consider these two components: +아래 두 컴포넌트가 있다고 가정해 봅시다. ```js function UserGreeting(props) { @@ -24,7 +24,7 @@ function GuestGreeting(props) { } ``` -We'll create a `Greeting` component that displays either of these components depending on whether a user is logged in: +이제 사용자의 로그인 상태에 맞게 위 컴포넌트 중 하나를 보여주는 `Greeting` 컴포넌트를 만듭니다, ```javascript{3-7,11,12} function Greeting(props) { @@ -42,15 +42,15 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZpVxNq?editors=0011) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/ZpVxNq?editors=0011) -This example renders a different greeting depending on the value of `isLoggedIn` prop. +이 예시는 `isLoggedIn` prop에 따라서 다른 인사말을 렌더링 합니다. -### Element Variables {#element-variables} +### 엘리먼트 변수 {#element-variables} -You can use variables to store elements. This can help you conditionally render a part of the component while the rest of the output doesn't change. +엘리먼트를 저장하기 위해 변수를 사용할 수 있습니다. 출력의 다른 부분은 변하지 않은 채로 컴포넌트의 일부를 조건부로 렌더링 할 수 있습니다. -Consider these two new components representing Logout and Login buttons: +로그아웃과 로그인 버튼을 나타내는 두 컴포넌트가 있다고 가정해 보세요. ```js function LoginButton(props) { @@ -70,9 +70,9 @@ function LogoutButton(props) { } ``` -In the example below, we will create a [stateful component](/docs/state-and-lifecycle.html#adding-local-state-to-a-class) called `LoginControl`. +아래의 예시에서는 `LoginControl`이라는 [유상태 컴포넌트](/docs/state-and-lifecycle.html#adding-local-state-to-a-class) 를 만들 것입니다. -It will render either `` or `` depending on its current state. It will also render a `` from the previous example: +이 컴포넌트는 현재 상태에 맞게 ``이나 ``을 렌더링합니다. 또한 이전 예시에서의 ``도 함께 렌더링합니다. ```javascript{20-25,29,30} class LoginControl extends React.Component { @@ -116,13 +116,13 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/QKzAgB?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/QKzAgB?editors=0010) -While declaring a variable and using an `if` statement is a fine way to conditionally render a component, sometimes you might want to use a shorter syntax. There are a few ways to inline conditions in JSX, explained below. +변수를 선언하고 `if`를 사용해서 조건부로 렌더링 하는 것은 좋은 방법이지만 더 짧은 구문을 사용하고 싶을 때가 있을 수 있습니다. 여러 조건을 JSX 안에서 인라인(inline)으로 처리할 방법 몇 가지를 아래에서 소개하겠습니다. -### Inline If with Logical && Operator {#inline-if-with-logical--operator} +### 논리 && 연산자로 If를 인라인으로 표현하기{#inline-if-with-logical--operator} -You may [embed any expressions in JSX](/docs/introducing-jsx.html#embedding-expressions-in-jsx) by wrapping them in curly braces. This includes the JavaScript logical `&&` operator. It can be handy for conditionally including an element: +JSX 안에는 중괄호를 이용해서 [표현식을 포함](/docs/introducing-jsx.html#embedding-expressions-in-jsx) 할 수 있습니다. 그 안에 JavaScript의 논리 연산자 `&&`를 사용하면 쉽게 엘리먼트를 조건부로 넣을 수 있습니다. ```js{6-10} function Mailbox(props) { @@ -146,17 +146,17 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/ozJddz?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/ozJddz?editors=0010) -It works because in JavaScript, `true && expression` always evaluates to `expression`, and `false && expression` always evaluates to `false`. +JavaScript에서 `true && expression`은 항상 `expression`으로 평가되고 `false && expression`은 항상 `false`로 평가됩니다. -Therefore, if the condition is `true`, the element right after `&&` will appear in the output. If it is `false`, React will ignore and skip it. +따라서 `&&` 뒤의 엘리먼트는 조건이 `true`일때 출력이 됩니다. 조건이 `false`라면 React는 무시합니다. -### Inline If-Else with Conditional Operator {#inline-if-else-with-conditional-operator} +### 조건부 연산자로 If-Else구문 인라인으로 표현하기{#inline-if-else-with-conditional-operator} -Another method for conditionally rendering elements inline is to use the JavaScript conditional operator [`condition ? true : false`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator). +엘리먼트를 조건부로 렌더링하는 다른 방법은 조건부 연산자인 [`condition ? true: false`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)를 사용하는 것입니다. -In the example below, we use it to conditionally render a small block of text. +아래의 예시에서는 짧은 구문을 조건부로 렌더링합니다. ```javascript{5} render() { @@ -169,7 +169,7 @@ render() { } ``` -It can also be used for larger expressions although it is less obvious what's going on: +가독성은 좀 떨어지지만, 더 큰 표현식에도 이 구문을 사용할 수 있습니다. ```js{5,7,9} render() { @@ -186,13 +186,13 @@ render() { } ``` -Just like in JavaScript, it is up to you to choose an appropriate style based on what you and your team consider more readable. Also remember that whenever conditions become too complex, it might be a good time to [extract a component](/docs/components-and-props.html#extracting-components). +JavaScript와 마찬가지로, 가독성이 좋다고 생각하는 방식을 선택하면 됩니다. 또한 조건이 너무 복잡하다면 [컴포넌트를 분리](/docs/components-and-props.html#extracting-components)하기 좋을 때 일 수도 있다는 것을 기억하세요. -### Preventing Component from Rendering {#preventing-component-from-rendering} +### 컴포넌트가 렌더링하는 것을 막기 {#preventing-component-from-rendering} -In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return `null` instead of its render output. +가끔 다른 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있을 수 있습니다. 이때는 렌더링 결과를 출력하는 대신 `null`을 반환하면 해결할 수 있습니다. -In the example below, the `` is rendered depending on the value of the prop called `warn`. If the value of the prop is `false`, then the component does not render: +아래의 예시에서는 ``가 `warn` prop의 값에 의해서 렌더링됩니다. prop이 `false`라면 컴포넌트는 렌더링하지 않게 됩니다. ```javascript{2-4,29} function WarningBanner(props) { @@ -238,6 +238,6 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/Xjoqwm?editors=0010) +[**CodePen에서 실행하기**](https://codepen.io/gaearon/pen/Xjoqwm?editors=0010) -Returning `null` from a component's `render` method does not affect the firing of the component's lifecycle methods. For instance `componentDidUpdate` will still be called. +컴포넌트의 `render` 메서드로부터 `null`을 반환하는 것은 생명주기 메서드 호출에 영향을 주지 않습니다. 그 예로 `componentDidUpdate`는 계속해서 호출되게 됩니다. \ No newline at end of file diff --git a/content/docs/context.md b/content/docs/context.md index 8e41a465f..6bdf02b01 100644 --- a/content/docs/context.md +++ b/content/docs/context.md @@ -4,57 +4,57 @@ title: Context permalink: docs/context.html --- -Context provides a way to pass data through the component tree without having to pass props down manually at every level. +context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다. -In a typical React application, data is passed top-down (parent to child) via props, but this can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree. +일반적인 React 애플리케이션에서 데이터는 위에서 아래로 (즉, 부모로부터 자식에게) props를 통해 전달되지만, 애플리케이션 안의 여러 컴포넌트들에 전해줘야 하는 props의 경우 (예를 들면 선호 로케일, UI 테마) 이 과정이 번거로울 수 있습니다. context를 이용하면, 트리 단계마다 명시적으로 props를 넘겨주지 않아도 많은 컴포넌트가 이러한 값을 공유하도록 할 수 있습니다. -- [When to Use Context](#when-to-use-context) -- [Before You Use Context](#before-you-use-context) +- [언제 context를 써야 할까](#when-to-use-context) +- [context를 사용하기 전에 고려할 것](#before-you-use-context) - [API](#api) - [React.createContext](#reactcreatecontext) - [Context.Provider](#contextprovider) - [Class.contextType](#classcontexttype) - [Context.Consumer](#contextconsumer) -- [Examples](#examples) - - [Dynamic Context](#dynamic-context) - - [Updating Context from a Nested Component](#updating-context-from-a-nested-component) - - [Consuming Multiple Contexts](#consuming-multiple-contexts) -- [Caveats](#caveats) -- [Legacy API](#legacy-api) +- [예시](#examples) + - [값이 변하는 context](#dynamic-context) + - [하위 컴포넌트에서 context 업데이트하기](#updating-context-from-a-nested-component) + - [여러 context 구독하기](#consuming-multiple-contexts) +- [주의사항](#caveats) +- [예전 API](#legacy-api) -## When to Use Context {#when-to-use-context} +## 언제 context를 써야 할까 {#when-to-use-context} -Context is designed to share data that can be considered "global" for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a "theme" prop in order to style the Button component: +context는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법입니다. 그러한 데이터로는 현재 로그인한 유저, 테마, 선호하는 언어 등이 있습니다. 예를 들어, 아래의 코드는 버튼 컴포넌트를 꾸미기 위해 테마(theme) props를 명시적으로 넘겨주고 있습니다. `embed:context/motivation-problem.js` -Using context, we can avoid passing props through intermediate elements: +context를 사용하면 중간에 있는 엘리먼트들에게 props를 넘겨주지 않아도 됩니다. `embed:context/motivation-solution.js` -## Before You Use Context {#before-you-use-context} +## context를 사용하기 전에 고려할 것 {#before-you-use-context} -Context is primarily used when some data needs to be accessible by *many* components at different nesting levels. Apply it sparingly because it makes component reuse more difficult. +context의 주된 용도는 다양한 레벨에 네스팅된 *많은* 컴포넌트에게 데이터를 전달하는 것입니다. context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 쓰세요. -**If you only want to avoid passing some props through many levels, [component composition](/docs/composition-vs-inheritance.html) is often a simpler solution than context.** +**여러 레벨에 걸쳐 props 넘기는 걸 대체하는 데에 context보다 [컴포넌트 합성](/docs/composition-vs-inheritance.html)이 더 간단한 해결책일 수도 있습니다.** -For example, consider a `Page` component that passes a `user` and `avatarSize` prop several levels down so that deeply nested `Link` and `Avatar` components can read it: +예를 들어 여러 단계 아래에 있는 `Link` 와 `Avatar` 컴포넌트에게 `user` 와 `avatarSize` 라는 props를 전달해야 하는 `Page` 컴포넌트를 생각해봅시다. ```js -// ... which renders ... +// ... 그 아래에 ... -// ... which renders ... +// ... 그 아래에 ... -// ... which renders ... +// ... 그 아래에 ... ``` -It might feel redundant to pass down the `user` and `avatarSize` props through many levels if in the end only the `Avatar` component really needs it. It's also annoying that whenever the `Avatar` component needs more props from the top, you have to add them at all the intermediate levels too. +실제로 사용되는 곳은 `Avatar` 컴포넌트 뿐인데 `user`와 `avatarSize` props를 여러 단계에 걸쳐 보내줘야 한다는 게 번거로워 보일 수 있습니다. 게다가 위에서 `Avatar` 컴포넌트로 보내줘야하는 props가 추가된다면 그 또한 중간 레벨에 모두 추가해줘야 합니다. -One way to solve this issue **without context** is to [pass down the `Avatar` component itself](/docs/composition-vs-inheritance.html#containment) so that the intermediate components don't need to know about the `user` prop: +[`Avatar` 컴포넌트 자체를 넘겨주면](/docs/composition-vs-inheritance.html#containment) **context를 사용하지 않고** 이를 해결할 수 있습니다. 그러면 중간에 있는 컴포넌트들이 `user`나 `avatarSize` 에 대해 전혀 알 필요가 없습니다. ```js function Page(props) { @@ -67,21 +67,21 @@ function Page(props) { return ; } -// Now, we have: - -// ... which renders ... +// 이제 이렇게 쓸 수 있습니다. + +// ... 그 아래에 ... -// ... which renders ... +// ... 그 아래에 ... -// ... which renders ... +// ... 그 아래에 ... {props.userLink} ``` -With this change, only the top-most Page component needs to know about the `Link` and `Avatar` components' use of `user` and `avatarSize`. +이렇게 바꾸면 `Link`와 `Avatar` 컴포넌트가 `user` 와 `avatarSize` props를 쓴다는 걸 알아야 하는 건 가장 위에 있는 `Page` 뿐입니다. -This *inversion of control* can make your code cleaner in many cases by reducing the amount of props you need to pass through your application and giving more control to the root components. However, this isn't the right choice in every case: moving more complexity higher in the tree makes those higher-level components more complicated and forces the lower-level components to be more flexible than you may want. +이러한 *제어의 역전(inversion of control)* 을 이용하면 넘겨줘야 하는 props의 수는 줄고 최상위 컴포넌트의 제어력은 더 커지기 때문에 더 깔끔한 코드를 쓸 수 있는 경우가 많습니다. 하지만 이 방법이 항상 옳은 것은 아닙니다. 복잡한 로직을 상위로 옮기면 이 상위 컴포넌트들은 더 난해해지기 마련이고 하위 컴포넌트들은 필요 이상으로 유연해져야 합니다. -You're not limited to a single child for a component. You may pass multiple children, or even have multiple separate "slots" for children, [as documented here](/docs/composition-vs-inheritance.html#containment): +자식으로 둘 수 있는 컴포넌트의 수에 제한은 없습니다. 여러 컴포넌트, 혹은 여러 개로 구분된 "슬롯"을 넘기는 방법에 대해서는 [여기](/docs/composition-vs-inheritance.html#containment)를 참조하세요. ```js function Page(props) { @@ -103,9 +103,9 @@ function Page(props) { } ``` -This pattern is sufficient for many cases when you need to decouple a child from its immediate parents. You can take it even further with [render props](/docs/render-props.html) if the child needs to communicate with the parent before rendering. +이 패턴을 사용하면 자식 컴포넌트와 직속 부모를 분리(decouple)하는 문제는 대개 해결할 수 있습니다. 더 나아가 [render props](/docs/render-props.html)를 이용하면 렌더링 되기 전부터 자식 컴포넌트가 부모 컴포넌트와 소통하게 할 수 있습니다. -However, sometimes the same data needs to be accessible by many components in the tree, and at different nesting levels. Context lets you "broadcast" such data, and changes to it, to all components below. Common examples where using context might be simpler than the alternatives include managing the current locale, theme, or a data cache. +하지만 같은 데이터를 트리 안 여러 레벨이 있는 많은 컴포넌트에 주어야 할 때도 있습니다. 이런 데이터 값이 변할 때마다 모든 하위 컴포넌트에게 널리 "방송"하는 것이 context입니다. 흔히 예시로 드는 선호 로케일, 테마, 데이터 캐시 등을 관리하는 데 있어서는 일반적으로 context를 사용하는 게 가장 편리합니다. ## API {#api} @@ -115,27 +115,27 @@ However, sometimes the same data needs to be accessible by many components in th const MyContext = React.createContext(defaultValue); ``` -Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching `Provider` above it in the tree. +Context 객체를 만듭니다. Context 객체를 구독하고 있는 컴포넌트를 렌더링할 때 React는 트리 상위에서 가장 가까이 있는 짝이 맞는 `Provider`로부터 현재값을 읽습니다. -The `defaultValue` argument is **only** used when a component does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them. Note: passing `undefined` as a Provider value does not cause consuming components to use `defaultValue`. +`defaultValue` 매개변수는 트리 안에서 적절한 Provider를 **찾지 못햇을 때에만** 쓰이는 값입니다. 컴포넌트를 독립적으로 테스트할 때 유용한 값입니다. Provider를 통해 `undefined`을 값으로 보낸다고 해도 구독 컴포넌트들이 `defaultValue` 를 읽지는 않는다는 점에 유의하세요. ### `Context.Provider` {#contextprovider} ```js - + ``` -Every Context object comes with a Provider React component that allows consuming components to subscribe to context changes. +Context 오브젝트에 포함된 React 컴포넌트인 Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알리는 역할을 합니다. -Accepts a `value` prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree. +Provider 는 `value` prop를 받아서 이 값을 하위에 있는 컴포넌트에게 전달합니다. 값을 전달받을 수 있는 컴포넌트의 수에 제한은 없습니다. Provider 하위에 또 다른 Provider를 배치하는 것도 가능하며, 이 경우 하위 Provider의 값이 우선시됩니다. -All consumers that are descendants of a Provider will re-render whenever the Provider's `value` prop changes. The propagation from Provider to its descendant consumers is not subject to the `shouldComponentUpdate` method, so the consumer is updated even when an ancestor component bails out of the update. +Provider 하위에서 context를 구독하는 모든 컴포넌트는 Provider의 `value` prop가 바뀔 때마다 다시 렌더링 됩니다. 이러한 전파는 `shouldComponentUpdate`의 영향을 받지 않기 때문에 중간에 있는 컴포넌트가 업데이트를 중지한다고 해도 트리 끝에 있는 컴포넌트까지 전달됩니다. -Changes are determined by comparing the new and old values using the same algorithm as [`Object.is`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description). +context 값의 바뀌었는지 여부는 [`Object.is`](//developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is#설명)와 동일한 알고리즘을 사용해 이전 값과 새로운 값을 비교해 측정됩니다. -> Note -> -> The way changes are determined can cause some issues when passing objects as `value`: see [Caveats](#caveats). +> 주의 +> +> 위와 같은 방식으로 변화를 측정하기 때문에 객체를 `value`로 보내는 경우 다소 문제가 생길 수 있습니다. [주의사항](#caveats)을 참조하세요. ### `Class.contextType` {#classcontexttype} @@ -143,7 +143,7 @@ Changes are determined by comparing the new and old values using the same algori class MyClass extends React.Component { componentDidMount() { let value = this.context; - /* perform a side-effect at mount using the value of MyContext */ + /* MyContext의 값을 이용한 코드 */ } componentDidUpdate() { let value = this.context; @@ -155,27 +155,25 @@ class MyClass extends React.Component { } render() { let value = this.context; - /* render something based on the value of MyContext */ + /* ... */ } } MyClass.contextType = MyContext; ``` +[`React.createContext()`](#reactcreatecontext)로 생성한 Context 객체를 원하는 클래스의 `contextType` 프로퍼티로 지정할 수 있습니다. 그러면 그 클래스 안에서 `this.context`를 이용해 해당 Context의 가장 가까운 Provider를 찾아 그 값을 읽을 수 있게됩니다. 이 값은 render를 포함한 모든 컴포넌트 생명주기 매서드에서 사용할 수 있습니다. -The `contextType` property on a class can be assigned a Context object created by [`React.createContext()`](#reactcreatecontext). This lets you consume the nearest current value of that Context type using `this.context`. You can reference this in any of the lifecycle methods including the render function. - -> Note: +> 주의 > -> You can only subscribe to a single context using this API. If you need to read more than one see [Consuming Multiple Contexts](#consuming-multiple-contexts). +> 이 API를 사용하면 하나의 context만 구독할 수 있습니다. 여러 context를 구독하기 위해서는 [여러 context 구독하기](#consuming-multiple-contexts)를 참조하세요. > -> If you are using the experimental [public class fields syntax](https://babeljs.io/docs/plugins/transform-class-properties/), you can use a **static** class field to initialize your `contextType`. - +> 실험적 기능인 [public class fields syntax](https://babeljs.io/docs/plugins/transform-class-properties/)를 사용하고 있다면 **정적** 클래스 프로퍼티로 `contextType`을 지정할 수 있습니다. ```js class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; - /* render something based on the value */ + /* context 값을 이용한 렌더링 */ } } ``` @@ -184,23 +182,23 @@ class MyClass extends React.Component { ```js - {value => /* render something based on the context value */} + {value => /* context 값을 이용한 렌더링 */} ``` -A React component that subscribes to context changes. This lets you subscribe to a context within a [function component](/docs/components-and-props.html#function-and-class-components). +context 변화를 구독하는 React 컴포넌트입니다. [함수 컴포넌트](/docs/components-and-props.html#function-and-class-components)안에서 context를 읽기 위해서 쓸 수 있습니다. -Requires a [function as a child](/docs/render-props.html#using-props-other-than-render). The function receives the current context value and returns a React node. The `value` argument passed to the function will be equal to the `value` prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the `value` argument will be equal to the `defaultValue` that was passed to `createContext()`. +Context.Consumer의 자식은 [함수](/docs/render-props.html#using-props-other-than-render)여야합니다. 이 함수는 context의 현재값을 받고 React 노드를 반환합니다. 이 함수가 받는 `value` 매개변수 값은 해당 context의 Provider 중 상위 트리에서 가장 가까운 Provider의 `value` prop과 동일합니다. 상위에 Provider가 없다면 `value` 매개변수 값은 `createContext()`에 보냈던 `defaultValue`와 동일할 것입니다. -> Note -> -> For more information about the 'function as a child' pattern, see [render props](/docs/render-props.html). +> 주의 +> +>함수를 자식으로 받는 패턴에 대해서는 [render props](/docs/render-props.html)을 참조하세요. -## Examples {#examples} +## 예시 {#examples} -### Dynamic Context {#dynamic-context} +### 값이 변하는 context {#dynamic-context} -A more complex example with dynamic values for the theme: +theme 값이 변하는 좀 더 복잡한 예시입니다. **theme-context.js** `embed:context/theme-detailed-theme-context.js` @@ -211,9 +209,9 @@ A more complex example with dynamic values for the theme: **app.js** `embed:context/theme-detailed-app.js` -### Updating Context from a Nested Component {#updating-context-from-a-nested-component} +### 하위 컴포넌트에서 context 업데이트하기 {#updating-context-from-a-nested-component} -It is often necessary to update the context from a component that is nested somewhere deeply in the component tree. In this case you can pass a function down through the context to allow consumers to update the context: +컴포넌트 트리 하위 깊숙이 있는 컴포넌트에서 context를 업데이트 해야 할 때가 종종 있습니다. 그럴 때는 context를 통해 매서드를 보내면 됩니다. **theme-context.js** `embed:context/updating-nested-context-context.js` @@ -224,28 +222,27 @@ It is often necessary to update the context from a component that is nested some **app.js** `embed:context/updating-nested-context-app.js` -### Consuming Multiple Contexts {#consuming-multiple-contexts} +### 여러 context 구독하기 {#consuming-multiple-contexts} -To keep context re-rendering fast, React needs to make each context consumer a separate node in the tree. +각 context마다 Consumer를 개별 노드로 만들게 설계되어있는데, 이것은 context 변화로 인해 다시 렌더링하는 과정을 빠르게 유지하기 위함입니다. `embed:context/multiple-contexts.js` -If two or more context values are often used together, you might want to consider creating your own render prop component that provides both. +둘 이상의 context 값이 함께 쓰이는 경우가 많다면 그 값들을 한 번에 받는 render prop 컴포넌트를 만드는 것을 고려해보세요. -## Caveats {#caveats} +## 주의사항 {#caveats} -Because context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider's parent re-renders. For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for `value`: +다시 렌더링할지 여부를 정할 때 참조(reference)를 확인하기 때문에, Provider의 부모가 렌더링 될 때마다 불필요하게 하위 컴포넌트가 다시 렌더링 되는 문제가 생길 수도 있습니다. 예를 들어 아래 코드는 `value`가 바뀔 때마다 매번 새로운 객체가 생성되므로 Provider가 렌더링 될 때마다 그 하위에서 구독하고 있는 컴포넌트 모두가 다시 렌더링 될 것입니다. `embed:context/reference-caveats-problem.js` -To get around this, lift the value into the parent's state: +이를 피하기 위해서는 값을 부모의 state로 끌어올리세요. `embed:context/reference-caveats-solution.js` -## Legacy API {#legacy-api} +## 예전 API {#legacy-api} -> Note -> -> React previously shipped with an experimental context API. The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. The legacy API will be removed in a future major React version. Read the [legacy context docs here](/docs/legacy-context.html). - +> 주의 +> +> 이전 버전의 React에 실험적인 단계의 context API가 존재한 적이 있습니다. 예전 API는 모든 16.x 버전에서 지원될 예정이지만 새로운 API로 옮길 것을 권장합니다. 다음 메이저 배포에서 예전 API는 삭제될 것입니다. 예전 API 문서는 [여기](/docs/legacy-context.html)에 있습니다. diff --git a/content/docs/faq-ajax.md b/content/docs/faq-ajax.md index 102e1c07e..1b2ea44af 100644 --- a/content/docs/faq-ajax.md +++ b/content/docs/faq-ajax.md @@ -1,24 +1,24 @@ --- id: faq-ajax -title: AJAX and APIs +title: AJAX 와 APIs permalink: docs/faq-ajax.html layout: docs category: FAQ --- -### How can I make an AJAX call? {#how-can-i-make-an-ajax-call} +### 어떻게 AJAX 호출을 할 수 있을까요? {#how-can-i-make-an-ajax-call} -You can use any AJAX library you like with React. Some popular ones are [Axios](https://github.com/axios/axios), [jQuery AJAX](https://api.jquery.com/jQuery.ajax/), and the browser built-in [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). +당신이 선호하는 AJAX 라이브러리를 React와 함께 사용할 수 있습니다. 유명한 라이브러리로는 [Axios](https://github.com/axios/axios), [jQuery AJAX](https://api.jquery.com/jQuery.ajax/), 그리고 브라우저에 내장된 [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) 등이 있습니다. -### Where in the component lifecycle should I make an AJAX call? {#where-in-the-component-lifecycle-should-i-make-an-ajax-call} +### 컴포넌트의 생명주기 중 어디에서 AJAX 호출을 할 수 있나요? {#where-in-the-component-lifecycle-should-i-make-an-ajax-call} -You should populate data with AJAX calls in the [`componentDidMount`](/docs/react-component.html#mounting) lifecycle method. This is so you can use `setState` to update your component when the data is retrieved. +AJAX 호출을 통한 데이터는 생명주기 메서드 중 [`componentDidMount`](/docs/react-component.html#mounting) 안에 추가되어야 합니다. 이는 데이터를 받아 올 때 `setState`를 통하여 컴포넌트를 업데이트하기 위함입니다. -### Example: Using AJAX results to set local state {#example-using-ajax-results-to-set-local-state} +### 예시: 로컬 state를 설정하기 위해 AJAX 결과 사용하기 {#example-using-ajax-results-to-set-local-state} -The component below demonstrates how to make an AJAX call in `componentDidMount` to populate local component state. +아래 컴포넌트는 로컬 컴포넌트의 state를 채우기 위하여 `componentDidMount` 안에서 어떻게 AJAX 호출을 만드는지 보여 줍니다. -The example API returns a JSON object like this: +API 예시는 다음과 같은 JSON 객체를 반환합니다. ``` { @@ -50,9 +50,9 @@ class MyComponent extends React.Component { items: result.items }); }, - // Note: it's important to handle errors here - // instead of a catch() block so that we don't swallow - // exceptions from actual bugs in components. + // 주의: 컴포넌트의 실제 버그에서 발생하는 예외사항들을 넘기지 않도록 + // 에러를 catch() 블록(block)에서 처리하기보다는 + // 이 부분에서 처리하는 것이 중요합니다. (error) => { this.setState({ isLoaded: true, diff --git a/content/docs/faq-build.md b/content/docs/faq-build.md index b071cc131..6ec21b681 100644 --- a/content/docs/faq-build.md +++ b/content/docs/faq-build.md @@ -1,32 +1,32 @@ --- id: faq-build -title: Babel, JSX, and Build Steps +title: Babel, JSX, 그리고 빌드 과정들 permalink: docs/faq-build.html layout: docs category: FAQ --- -### Do I need to use JSX with React? {#do-i-need-to-use-jsx-with-react} +### React에 JSX를 꼭 사용해야 하나요? {#do-i-need-to-use-jsx-with-react} -No! Check out ["React Without JSX"](/docs/react-without-jsx.html) to learn more. +아니요! 더 자세한 내용을 위해 ["JSX 없이 React 사용하기"](/docs/react-without-jsx.html) 를 확인해 주세요. -### Do I need to use ES6 (+) with React? {#do-i-need-to-use-es6--with-react} +### React에 ES6 (+)를 꼭 사용해야 하나요? {#do-i-need-to-use-es6--with-react} -No! Check out ["React Without ES6"](/docs/react-without-es6.html) to learn more. +아니요! 더 자세한 내용을 위해 ["ES6 없이 React 사용하기"](/docs/react-without-es6.html) 를 확인해 주세요. -### How can I write comments in JSX? {#how-can-i-write-comments-in-jsx} +### JSX에서 어떻게 주석을 달 수 있나요? {#how-can-i-write-comments-in-jsx} ```jsx
- {/* Comment goes here */} + {/* 주석은 여기에 */} Hello, {name}!
``` ```jsx
- {/* It also works - for multi-line comments. */} + {/* 여러 줄의 + 주석도 가능합니다. */} Hello, {name}!
``` diff --git a/content/docs/forms.md b/content/docs/forms.md index 1a8b599d5..f5c7d88c1 100644 --- a/content/docs/forms.md +++ b/content/docs/forms.md @@ -1,6 +1,6 @@ --- id: forms -title: Forms +title: 폼 permalink: docs/forms.html prev: lists-and-keys.html next: lifting-state-up.html @@ -9,7 +9,7 @@ redirect_from: - "docs/forms-zh-CN.html" --- -HTML form elements work a little bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, this form in plain HTML accepts a single name: +HTML 폼 엘리먼트는 폼 엘리먼트 자체가 내부 상태를 가지기 때문에, React의 다른 DOM 엘리먼트와 조금 다르게 동작합니다. 예를 들어, 순수한 HTML에서 이 폼은 name을 입력받습니다. ```html
@@ -21,15 +21,15 @@ HTML form elements work a little bit differently from other DOM elements in Reac
``` -This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it's convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called "controlled components". +이 폼은 사용자가 폼을 제출하면 새로운 페이지로 이동하는 기본 HTML 폼 동작을 수행합니다. React에서 동일한 동작을 원한다면 그대로 사용하면 됩니다. 그러나 대부분의 경우, JavaScript 함수로 폼의 제출을 처리하고 사용자가 폼에 입력한 데이터에 접근하도록 하는 것이 편리합니다. 이를 위한 표준 방식은 "제어 컴포넌트 (controlled components)"라고 불리는 기술을 이용하는 것입니다. -## Controlled Components {#controlled-components} +## 제어 컴포넌트 (Controlled Component) {#controlled-components} -In HTML, form elements such as ``, ` ``` -In React, a `