Вступление.0 Вся схема (кликабельна)
Итак... взгляните. Не торопитесь. В целом она выглядит сложной, но на самом деле в ней описаны всего лишь два процеса: mount и update. Я пропустил unmount, потому что по сути это просто "mount наоборот", и убрав его, можно упростить схему. Кроме того, это не 100% переложение кода, только основных его частей, которые описывают архитектуру. В целом, это около 60% кода, но остальные 40% мало помогают выразительности визуализации, поэтому я, опять же, их опустил.
С первого взгляда вы наверняка заметите на схеме множество цветов. Каждая логическая единица (фигура на схема) раскрашена в цвет родительского модуля. Например, methodA
будет красным, если он вызывается из moduleB
, который красный. Ниже представлена легенда для модулей на схеме, с путями к каждому файлу.
Вступление.1 Цвета модулей (кликабельно)
Давай поместим их на схему чтобы увидеть зависимости между модулями.
Вступление.2 Зависимости модулей (кликабельно)
Как вы наверное знаете, React разрабатывается с поддержкой множества окружений.
- Мобильные устройства (ReactNative)
- Браузеры (ReactDOM)
- Серверный рендеринг
- ReactART (для рисования векторной графики с помощью React'а)
- и т.д.
В результате, на самом деле число файлов гораздо больше, чем кажется по схеме. Ниже представлена та же самая схема с включением в нее поддержки разных окружений.
Вступление.3 Зависимости платформ (кликабельно)
Как вы видите, некоторые элементы задвоились. Таким образом показано, что они имеют раздельные реализации под каждую платфору. Давайте возьмем что-нибудь простое, например ReactEventListener. Очевидно, что его реализация для разных платформ будет разной! Технически, как вы понимаете, зависимые модули для этих платформ должны быть как-то подключены или внедрены в текущий логический поток выполнения, и таких точек подключения на самом деле много. Поскольку их использование это часть стандартного паттерна "Компоновщик", я решил опустить их. Опять же, для упрощения.
Давайте познакомимся с логическим потоком выполнения кода для React DOM в обычном браузере. Это наиболее используемая платформа, и она полностью покрывает все архитектурные идеи React'а, так что почему бы нам и не взять ее.
Какой наилучший способ изучить код фреймворка или библиотеки? Правильно, прочитать и отладить код. Хорошо, мы будем отлаживать два процесса: ReactDOM.render и component.setState, которые транслируются в mount и update. Давайте глянем на код, с которого мы смогли бы бы начать. Что нам понадобится? Наверное, несколько маленьких компонентов с простыми рендерами, так проще их будет отлаживать.
class ChildCmp extends React.Component {
render() {
return <div> {this.props.childMessage} </div>
}
}
class ExampleApplication extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'нет сообщения'};
}
componentWillMount() {
//...
}
componentDidMount() {
/* setTimeout(()=> {
this.setState({ message: 'сообщение в состоянии по таймауту' });
}, 1000); */
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
return true;
}
componentDidUpdate(prevProps, prevState, prevContext) {
//...
}
componentWillReceiveProps(nextProps) {
//...
}
componentWillUnmount() {
//...
}
onClickHandler() {
/* this.setState({ message: 'сообщение в состоянии по щелчку' }); */
}
render() {
return <div>
<button onClick={this.onClickHandler.bind(this)}> Кнопка обновления состояния </button>
<ChildCmp childMessage={this.state.message} />
А также некоторый текст!
</div>
}
}
ReactDOM.render(
<ExampleApplication hello={'world'} />,
document.getElementById('container'),
function() {}
);
Итак, можно начинать. Давайте перейдем к первой части схемы. Шаг за шагом, мы пройдем ее целиком.