diff --git a/content/docs/design-principles.md b/content/docs/design-principles.md index 9e10f39d5..553096b3b 100644 --- a/content/docs/design-principles.md +++ b/content/docs/design-principles.md @@ -1,6 +1,6 @@ --- id: design-principles -title: Design Principles +title: Принципы проектирования React layout: contributing permalink: docs/design-principles.html prev: implementation-notes.html @@ -8,85 +8,86 @@ redirect_from: - "contributing/design-principles.html" --- -We wrote this document so that you have a better idea of how we decide what React does and what React doesn't do, and what our development philosophy is like. While we are excited to see community contributions, we are not likely to choose a path that violates one or more of these principles. +Мы написали этот документ, чтобы у вас было лучшее представление о том, как мы решаем, что делает React, а что нет, и какова наша философия разработки. Хоть мы и рады видеть вклад сообщества, мы вряд ли выберем путь, который нарушает один или несколько из этих принципов. ->**Note:** +>**Примечание:** > ->This document assumes a strong understanding of React. It describes the design principles of *React itself*, not React components or applications. +>Эта статья подразумевает глубокое понимание React. В ней описаны концепции разработки *самого React*, но не React-компонентов или приложений. > ->For an introduction to React, check out [Thinking in React](/docs/thinking-in-react.html) instead. +>Для знакомства с React почитайте главу [Философия React](/docs/thinking-in-react.html). -### Composition {#composition} +### Композиция {#composition} -The key feature of React is composition of components. Components written by different people should work well together. It is important to us that you can add functionality to a component without causing rippling changes throughout the codebase. +Ключевая возможность React — это композиция компонентов. Компоненты, написанные разными людьми, должны хорошо работать вместе. Для нас важно, чтобы вы могли добавлять в компонент функциональность, не вызывая волну изменений по всему коду. -For example, it should be possible to introduce some local state into a component without changing any of the components using it. Similarly, it should be possible to add some initialization and teardown code to any component when necessary. +Например, должна быть возможность вводить некое внутреннее состояние в компонент без изменения зависящих от него компонентов. Также должна быть возможность добавлять при необходимости код инициализации и разрушения в любой компонент. -There is nothing "bad" about using state or lifecycle methods in components. Like any powerful feature, they should be used in moderation, but we have no intention to remove them. On the contrary, we think they are integral parts of what makes React useful. We might enable [more functional patterns](https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State) in the future, but both local state and lifecycle methods will be a part of that model. +Нет ничего «плохого» в использовании состояния или методов жизненного цикла в компонентах. Как и любую мощную возможность, их стоит использовать в меру, но мы не собираемся их удалять. Напротив, мы считаем, что они являются неотъемлемой частью того, что делает React полезным. Возможно, мы добавим [больше паттернов функционального программирования](https://github.com/reactjs/react-future/tree/master/07%20-%20Returning%20State) в будущем, но как внутреннее состояние, так и методы жизненного цикла будут частью этой модели. -Components are often described as "just functions" but in our view they need to be more than that to be useful. In React, components describe any composable behavior, and this includes rendering, lifecycle, and state. Some external libraries like [Relay](https://facebook.github.io/relay/) augment components with other responsibilities such as describing data dependencies. It is possible that those ideas might make it back into React too in some form. +Компоненты часто описываются как «просто функции», но, по нашему мнению, они должны быть чем-то большим, чтобы быть полезными. Компоненты в React описывают поведение, которое можно композировать. Эта идея распространяется в том числе на рендеринг, жизненный цикл и состояние. Некоторые сторонние библиотеки, вроде [Relay](https://facebook.github.io/relay/), дополняют компоненты другими возможностями, например, описанием зависимостей данных. Вполне возможно, что эти идеи могут попасть в React в той или иной форме. -### Common Abstraction {#common-abstraction} +### Общая абстракция {#common-abstraction} -In general we [resist adding features](https://www.youtube.com/watch?v=4anAwXYqLG8) that can be implemented in userland. We don't want to bloat your apps with useless library code. However, there are exceptions to this. +В целом, мы [против добавления функциональности](https://www.youtube.com/watch?v=4anAwXYqLG8), которая может быть реализована в пользовательских приложениях. Мы не хотим раздувать ваше приложение бесполезным кодом библиотеки. Но и у этого правила есть свои исключения. -For example, if React didn't provide support for local state or lifecycle methods, people would create custom abstractions for them. When there are multiple abstractions competing, React can't enforce or take advantage of the properties of either of them. It has to work with the lowest common denominator. +Например, если бы React не предоставлял поддержку внутреннего состояния или методов жизненного цикла, люди бы создавали собственные абстракции для них. Когда есть несколько конкурирующих абстракций, React не может применять или использовать их свойства. Для работы React нужен некий наименьший общий знаменатель. -This is why sometimes we add features to React itself. If we notice that many components implement a certain feature in incompatible or inefficient ways, we might prefer to bake it into React. We don't do it lightly. When we do it, it's because we are confident that raising the abstraction level benefits the whole ecosystem. State, lifecycle methods, cross-browser event normalization are good examples of this. +Вот почему иногда мы добавляем возможности в сам React. Если мы замечаем, что какая-то возможность реализуется плохо совместимым или неэффективным способом во многих компонентах, мы можем захотеть внедрить эту возможность в React. Мы подходим к таким изменениям со всей серьёзностью. +Если мы добавляем новую возможность, значит мы уверены, что повышение уровня абстракции принесёт выгоду всей экосистеме. Хорошие примеры для этого — состояние, методы жизненного цикла, кросс-браузерная нормализация событий. -We always discuss such improvement proposals with the community. You can find some of those discussions by the ["big picture"](https://github.com/facebook/react/issues?q=is:open+is:issue+label:"Type:+Big+Picture") label on the React issue tracker. +Мы всегда обсуждаем с сообществом такие предложения по улучшению. Некоторые из этих обсуждений можно найти по метке [«big picture»](https://github.com/facebook/react/issues?q=is:open+is:issue+label:"Type:+Big+Picture") в трекере задач React. -### Escape Hatches {#escape-hatches} +### Лазейки {#escape-hatches} -React is pragmatic. It is driven by the needs of the products written at Facebook. While it is influenced by some paradigms that are not yet fully mainstream such as functional programming, staying accessible to a wide range of developers with different skills and experience levels is an explicit goal of the project. +React прагматичен. Это обусловлено потребностями продуктов, написанных в Facebook. Хоть на него и влияют некоторые не самые популярные парадигмы, такие как функциональное программирование, цель проекта — оставаться доступным для широкого круга разработчиков с разным уровнем опыта и навыками. -If we want to deprecate a pattern that we don't like, it is our responsibility to consider all existing use cases for it and [educate the community about the alternatives](/blog/2016/07/13/mixins-considered-harmful.html) before we deprecate it. If some pattern that is useful for building apps is hard to express in a declarative way, we will [provide an imperative API](/docs/more-about-refs.html) for it. If we can't figure out a perfect API for something that we found necessary in many apps, we will [provide a temporary subpar working API](/docs/legacy-context.html) as long as it is possible to get rid of it later and it leaves the door open for future improvements. +Если мы хотим отказаться от паттерна, который нам не нравится, на нас лежит ответственность рассмотреть все существующие варианты его использования и [проинформировать сообщество об альтернативах](/blog/2016/07/13/mixins-considered-harmful.html), прежде чем отказаться от него. Если какой-то полезный для создания приложений паттерн трудно описать декларативно, мы [предоставим для него императивный API](/docs/more-about-refs.html). Если мы не можем найти идеальный API для того, что мы считаем необходимым во многих приложениях, мы [предоставим временный, частично работающий API](/docs/legacy-context.html), при условии, что от него можно будет избавиться позже. Это оставляет открытой дверь для будущих улучшений. -### Stability {#stability} +### Стабильность {#stability} -We value API stability. At Facebook, we have more than 50 thousand components using React. Many other companies, including [Twitter](https://twitter.com/) and [Airbnb](https://www.airbnb.com/), are also heavy users of React. This is why we are usually reluctant to change public APIs or behavior. +Мы ценим стабильность API. У нас в Facebook более 50 тысяч компонентов, использующих React. Многие другие компании, включая [Twitter](https://twitter.com/) и [Airbnb](https://www.airbnb.com/), также активно используют React. Поэтому мы обычно нехотя меняем публичный API или поведение. -However we think stability in the sense of "nothing changes" is overrated. It quickly turns into stagnation. Instead, we prefer the stability in the sense of "It is heavily used in production, and when something changes, there is a clear (and preferably automated) migration path." +Однако, мы считаем переоценённой идею, что стабильность — это когда «ничего не меняется». Она быстро приводит к застою. Вместо этого, мы предпочитаем воспринимать стабильность в смысле «это много используется в продакшене и когда что-то меняется, существует четкий (и желательно автоматизированный) план миграции». -When we deprecate a pattern, we study its internal usage at Facebook and add deprecation warnings. They let us assess the impact of the change. Sometimes we back out if we see that it is too early, and we need to think more strategically about getting the codebases to the point where they are ready for this change. +Когда мы объявляем паттерн устаревшим, мы сперва изучаем как он используется внутри Facebook и добавляем предупреждения об устаревании. Это позволяет нам оценить масштабы последствий изменения. Иногда мы отменяем изменение, если видим, что ещё слишком рано приступать к его воплощению и нам нужно продумать стратегию продвижения кодовой базы к состоянию готовности. -If we are confident that the change is not too disruptive and the migration strategy is viable for all use cases, we release the deprecation warning to the open source community. We are closely in touch with many users of React outside of Facebook, and we monitor popular open source projects and guide them in fixing those deprecations. +Если мы уверены, что изменение не слишком большое и для всех случаев использования возможна миграция, то предупреждение об устаревании публикуется перед OSS-сообществом. Мы тесно общаемся со многими React-пользователями вне Facebook, следим за популярными OSS-проектами и помогаем им исправлять устаревший код. -Given the sheer size of the Facebook React codebase, successful internal migration is often a good indicator that other companies won't have problems either. Nevertheless sometimes people point out additional use cases we haven't thought of, and we add escape hatches for them or rethink our approach. +Учитывая огромный размер кодовой базы React в Facebook, успешная внутренняя миграция часто является хорошим индикатором того, что в других компаниях также не будет проблем. Тем не менее, люди иногда указывают на неучтенные варианты использования и мы добавляем лазейки или пересматриваем подход. -We don't deprecate anything without a good reason. We recognize that sometimes deprecations warnings cause frustration but we add them because deprecations clean up the road for the improvements and new features that we and many people in the community consider valuable. +Ничто не объявляется устаревшим без веской причины. Мы понимаем, что иногда предупреждения об устаревании разочаровывают. Но они вводятся, так как это открывает дорогу улучшениям и новым возможностям, которые мы и сообщество считаем важными. -For example, we added a [warning about unknown DOM props](/warnings/unknown-prop.html) in React 15.2.0. Many projects were affected by this. However fixing this warning is important so that we can introduce the support for [custom attributes](https://github.com/facebook/react/issues/140) to React. There is a reason like this behind every deprecation that we add. +Например, мы добавили [предупреждение о неизвестных DOM-свойствах](/warnings/unknown-prop.html) в React 15.2.0. Этим мы затронули многие проекты. Однако, исправление этого предупреждения важно для добавления в React поддержки [пользовательских атрибутов](https://github.com/facebook/react/issues/140). Подобная причина стоит за каждым объявлением об устаревании, которое мы добавляем. -When we add a deprecation warning, we keep it for the rest of the current major version, and [change the behavior in the next major version](/blog/2016/02/19/new-versioning-scheme.html). If there is a lot of repetitive manual work involved, we release a [codemod](https://www.youtube.com/watch?v=d0pOgY8__JM) script that automates most of the change. Codemods enable us to move forward without stagnation in a massive codebase, and we encourage you to use them as well. +При добавлении предупреждения об устаревании, мы оставляем его пока актуальна текущая мажорная версия, [изменяя поведение только в следующей мажорной версии](/blog/2016/02/19/new-versioning-scheme.html). Если изменение создаёт много повторяющейся ручной работы, мы публикуем [codemod-скрипт](https://www.youtube.com/watch?v=d0pOgY8__JM), который автоматизирует большую часть изменений. Codemod-скрипты дают нам возможность двигаться вперёд, не закапываясь в куче кода. Рекомендуем вам тоже их использовать. -You can find the codemods that we released in the [react-codemod](https://github.com/reactjs/react-codemod) repository. +Вы можете найти ранее опубликованные codemod-скрипты в [react-codemod](https://github.com/reactjs/react-codemod) репозитории. -### Interoperability {#interoperability} +### Совместимость {#interoperability} -We place high value in interoperability with existing systems and gradual adoption. Facebook has a massive non-React codebase. Its website uses a mix of a server-side component system called XHP, internal UI libraries that came before React, and React itself. It is important to us that any product team can [start using React for a small feature](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) rather than rewrite their code to bet on it. +Мы придаём большое значение совместимости с существующими системами и возможности постепенного внедрения. В Facebook есть много кода, написанного не на React. Сайт использует смесь из XHP — системы серверных компонент, внутренних UI-библиотек, которые пришли до React, и самого React. Для нас важно, чтобы любая продуктовая команда могла [начать использовать React для небольшой возможности](https://www.youtube.com/watch?v=BF58ZJ1ZQxY), а не делать ставку на переписывание своего кода. -This is why React provides escape hatches to work with mutable models, and tries to work well together with other UI libraries. You can wrap an existing imperative UI into a declarative component, and vice versa. This is crucial for gradual adoption. +По этой причине React предоставляет лазейки для работы с изменяемыми моделями и пытается хорошо работать вместе с другими UI-библиотеками. Вы можете обернуть существующий императивный UI в декларативный компонент и наоборот. Это очень важно для постепенного внедрения. -### Scheduling {#scheduling} +### Планирование {#scheduling} -Even when your components are described as functions, when you use React you don't call them directly. Every component returns a [description of what needs to be rendered](/blog/2015/12/18/react-components-elements-and-instances.html#elements-describe-the-tree), and that description may include both user-written components like `` and platform-specific components like `
`. It is up to React to "unroll" `` at some point in the future and actually apply changes to the UI tree according to the render results of the components recursively. +Даже если компоненты описаны как функции, при использовании React они не вызываются напрямую. Каждый компонент возвращает [описание того, что должно быть отрендерено](/blog/2015/12/18/react-components-elements-and-instances.html#elements-describe-the-tree). Описание может включать как пользовательские компоненты, такие как ``, так и платформо-зависимые компоненты, такие как `
`. В дальнейшем в какой-то момент React может «развернуть» `` и фактически применить изменения к UI-дереву в соответствии с результатами рекурсивного рендеринга компонентов. -This is a subtle distinction but a powerful one. Since you don't call that component function but let React call it, it means React has the power to delay calling it if necessary. In its current implementation React walks the tree recursively and calls render functions of the whole updated tree during a single tick. However in the future it might start [delaying some updates to avoid dropping frames](https://github.com/facebook/react/issues/6170). +Это тонкое, но сильное различие. Поскольку вы не вызываете этот функциональный компонент, а позволяете React вызывать его, это означает, что React может отложить вызов при необходимости. В текущей реализации React рекурсивно обходит дерево и вызывает функции рендера всего обновлённого дерева за один проход. Но в будущем он может начать [задерживать некоторые обновления, чтобы избежать потери кадров](https://github.com/facebook/react/issues/6170). -This is a common theme in React design. Some popular libraries implement the "push" approach where computations are performed when the new data is available. React, however, sticks to the "pull" approach where computations can be delayed until necessary. +Это частая тема в архитектуре React. Некоторые популярные библиотеки реализуют подход «прослушивание», когда вычисления выполняются при появлении новых данных. React, наоборот, придерживается подхода «опрашивание», когда вычисления могут быть запрошены при необходимости. -React is not a generic data processing library. It is a library for building user interfaces. We think that it is uniquely positioned in an app to know which computations are relevant right now and which are not. +React не является универсальной библиотекой обработки данных. Это библиотека для создания пользовательских интерфейсов. Мы считаем, что приложение должно знать какие вычисления сейчас актуальны, а какие нет. -If something is offscreen, we can delay any logic related to it. If data is arriving faster than the frame rate, we can coalesce and batch updates. We can prioritize work coming from user interactions (such as an animation caused by a button click) over less important background work (such as rendering new content just loaded from the network) to avoid dropping frames. +Если что-то находится вне экрана, можно отложить любую связанную с этим логику. Если данные поступают быстрее, чем кадры успевают обновиться, можно объединить их и обновлять пакетами. Мы можем приоритизировать работу, вызванную пользовательским взаимодействием (например, анимация нажатия кнопки), над менее важной фоновой работой (например, рендеринг только что загруженного из сети компонента), чтобы избежать потери кадров. -To be clear, we are not taking advantage of this right now. However the freedom to do something like this is why we prefer to have control over scheduling, and why `setState()` is asynchronous. Conceptually, we think of it as "scheduling an update". +Уточним, что это на сегодняшний день это ещё не реализовано. Однако, подобная свобода иллюстрирует, почему мы предпочитаем контролировать планирование и почему функция `setState()` работает асинхронно. Концептуально мы думаем об этом как о «планировании обновления». -The control over scheduling would be harder for us to gain if we let the user directly compose views with a "push" based paradigm common in some variations of [Functional Reactive Programming](https://en.wikipedia.org/wiki/Functional_reactive_programming). We want to own the "glue" code. +Нам будет сложнее контролировать планирование, если мы позволим пользователям использовать подход «выталкивание при наличии данных», распространённый в [функциональном реактивном программировании](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5#%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D1%80%D0%B5%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B). Мы хотим, чтобы наш код был «связующим». -It is a key goal for React that the amount of the user code that executes before yielding back into React is minimal. This ensures that React retains the capability to schedule and split work in chunks according to what it knows about the UI. +Ключевая задача для React — минимизировать количество пользовательского кода, выполняемого перед возвращением обратно в React. Это гарантирует, что React сохранит возможность планировать и разбивать работу на части в соответствии с тем, что ему известно о UI. -There is an internal joke in the team that React should have been called "Schedule" because React does not want to be fully "reactive". +В команде есть внутренняя шутка, что React должен был называться «Планировщик», потому что React не хочет быть полностью «реактивным». ### Developer Experience {#developer-experience} diff --git a/content/docs/nav.yml b/content/docs/nav.yml index 7cb2b0887..e03216e47 100644 --- a/content/docs/nav.yml +++ b/content/docs/nav.yml @@ -132,7 +132,7 @@ - id: implementation-notes title: Implementation Notes - id: design-principles - title: Design Principles + title: Принципы проектирования React - title: FAQ items: - id: faq-ajax