React
Сообщество изучает возможность использованияReact
Синтаксис программы для разработки небольшого способа, один из более известных проектовTaro
,nanachi
. при использованииReact
Сложность апплета разработки грамматики в основном заключается вJSX
Грамматически,JSX
По сутиJS
, что слишком гибко по сравнению со статическим шаблоном небольшой программы. Новая идея, упомянутая в этой статье, состоит в том, чтобы иметь дело сJSX
Новые представления о грамматике, представляющей собой более динамичный процесс мышления, по сравнению с существующей схемой, в принципе не ограничивают никаких ограничений.JSX
Написание, позвольте вамНастоящий способ ReactИмея дело с небольшими программами, я надеюсь, что эта новая идея может дать любому, кто заинтересован в использованииReact
Вдохновение от людей, которые разработали апплет.
Ограничения существующего мышления
Прежде чем предлагать новые идеи, давайте взглянем наTaro(最新版1.3)
,nanachi
Это как небольшая побочная программа обработкиJSX
грамматический. Проще говоря, в основном черезфаза компиляцииПучокJSX
Преобразование в эквивалентный апплетwxml
приходитьReact
Код работает на стороне апплета.
Например, какReact
логическое выражение:
xx && <Text>Hello</Text>
будет преобразовано в эквивалентный апплет с директивой wx:if:
<Text wx:if="{{xx}}">Hello</Text>
СюдаJSX
обработки, в основном вфаза компиляции, он зависит отфаза компиляцииизИнформацияКоллекция, взяв приведенный выше пример, должна определить логические выражения, а затем выполнить соответствующие действия.wx:if
конверсионная обработка.
Этофаза компиляцииКакие проблемы и ограничения? Проиллюстрируем следующим примером:
class App extends React.Component {
render () {
const a = <Text>Hello</Text>
const b = a
return (
<View>
{b}
</View>
)
}
}
Сначала мы объявляемconst a = <Text>Hello</Text>
, затем поставьтеa
назначен наb
, давайте посмотрим на последнюю версиюTaro 1.3
преобразования, как показано ниже:
Этот пример не особенно сложен, но сообщает об ошибке.
Чтобы понять, почему приведенный выше код сообщает об ошибке, мы должны сначала понятьфаза компиляции. По сути, на этапе компиляции код представляет собой «строку», ифаза компиляцииПлан обработки, необходимо проанализировать нужную информацию из этой «строки» (черезAST
, обычный и т. д.), а затем выполните соответствующую эквивалентную обработку преобразования.
Для приведенного выше примера, что нужно сделать эквивалентно? нуждаемся в насфаза компиляцииАнализb
даJSX
Фрагмент:b = a = <Text>Hello</Text>
, затем поставьте<View>{b}</View>
середина{b}
Эквивалентно заменить на<Text>Hello</Text>
. Однако вфаза компиляциичтобы быть увереннымb
Значение очень трудно. Некоторые люди говорят, что можно вернуться назад, чтобы определить значение b. Это не невозможно, но учтите это, потому чтоb = a
, затем убедитесьa
значение, этоa
Как определить его стоимость? нуждаться вb
Определяется в цепочке областей видимости, к которой можно получить доступa
,Однакоa
В свою очередь, может назначить другие переменные, после того, как ситуация не является простой заданием цикла, возникает во время такого вызова функции, функциональная информация о времени выполнения тройных решений, след не удалось, еслиa
Это переменная, висящая на глобальном объекте, и отследить ее тем более невозможно.
так вфаза компиляциине легко определитьb
значения.
Давайте подробнее рассмотрим сообщение об ошибке на изображении выше:a is not defined
.
зачем говоритьa
А как насчет неопределенного? Это связано с другой проблемой, мы знаем<Text>Hello</Text>
, что на самом деле эквивалентноReact.createElement(Text, null, 'Hello')
,а такжеReact.createElement
Возвращаемое значение метода является обычнымJS
объект, как
// ReactElement对象
{
tag: Text,
props: null,
children: 'Hello'
...
}
Таким образом, приведенный выше код находится вJS
Операционная среда в реальном времени, вероятно, эквивалентна следующему:
class App extends React.Component {
render () {
const a = {
tag: Text,
props: null,
children: 'Hello'
...
}
const b = a
return {
tag: View,
props: null,
children: b
...
}
}
}
Однако мы только что сказали, что этап компиляции требуетJSX
Чтобы сделать эквивалентную обработку, вам нужно поставитьJSX
Перевести вwxml
,так<Text>Hello</Text>
этоJSX
Фрагменты обрабатываются особым образом,a
Это больше не обычноеjs
Объекты, здесь мы видимa
Переменная даже теряется, что обнажает серьезную проблему:Семантика кода нарушена, то есть из-за схемы времени компиляции дляJSX
специальная обработка, семантика кода, фактически работающего в апплете, отличается от того, что вы ожидали. Это скорее головная боль.
новые идеи
потому чтовремя компиляцииСхема, с указанными выше ограничениями, часто вызывает у вас «я все еще пишуReact
? "Это чувство.
Далее мы представляем совершенно новую идею обработки, которая используется во время работы апплета и реальногоReact
почти неразличим, не меняет семантику кода,JSX
выражения будут обрабатываться только какReact.createElement
Вызов метода, когда он на самом деле работает, это обычноеjs
Шаг 1: Дайте каждому независимомуJSX
Фрагменты однозначно идентифицируютсяuuid
, предполагая, что у нас есть следующий код:
const a = <Text uuid="000001">Hello</Text>
const y = <View uuid="000002">
<Image/>
<Text/>
</View>
мы даемa
фрагмент,y
фрагмент добавленuuid
Атрибуты
Шаг второй:React
Кодbabel
Переход к коду, который апплет может распознать, например.JSX
Фрагмент с эквивалентомReact.createElement
заменить и т.д.
const a = React.createElement(Text, {
uuid: "000001"
}, "Hello");
Шаг 3: Извлеките каждый независимыйJSX
Фрагмент с апплетомtemplate
упаковать, сгенерироватьwxml
документ
<template name="000001">
<Text>Hello</Text>
</template>
<template name="000002">
<View uuid="000002">
<Image/>
<Text/>
</View>
</template>
<!--占位template-->
<template is="{{uiDes.name}}" data="{{...uiDes}}"/>
Обратите внимание на каждыйtemplate
изname
логотип иJSX
Уникальный идентификатор фрагментаuuid
это то же самое. Наконец, в конце необходимо сгенерировать шаблон-заполнитель:<template is="{{uiDes.name}}" data="{{...uiDes}}"/>
.
Шаг 4: изменитьReactDOM.render
рекурсия (React 16.x
После этого не рекурсивным способом) процесс, рекурсивная фаза выполнения, агрегацияJSX
сегментированныйuuid
свойства, генерировать и возвращатьuiDes
структура данных.
Пятый шаг: сгенерирован четвертый шагuiDes
, передается в среду апплета, апплетuiDes
Установить шаблон заполнителя<template is="{{uiDes.name}}" data="{{...uiDes}}"/>
, который отображает окончательный вид.
Мы используем вышеперечисленноеApp
пример компонента, чтобы проиллюстрировать весь процесс, сначалаjs
Код будет экранирован как:
class App extends React.Component {
render () {
const a = React.createElement(Text, {uuid: "000001"}, "Hello");
const b = a
return (
React.createElement(View, {uuid: "000002"} , b);
)
}
}
При созданииwxml
документ:
<template name="000001">
<Text>Hello</Text>
</template>
<template name="000002">
<View>
<template is="{{child0001.name}}" data="{{...child0001}}"/>
</View>
</template>
<!--占位template-->
<template is="{{uiDes.name}}" data="{{...uiDes}}"/>
После использования нашего пользовательскогоrender
воплощать в жизньReactDOM.render(<App/>, parent)
. существуетrender
В рекурсивном процессе помимо рутинного создания экземпляров компонентов и выполнения жизненного цикла будет выполняться дополнительный сбор компонентов в процессе выполнения.uuid
идентификация, последнее поколениеuiDes
объект
const uiDes = {
name: "000002",
child0001: {
name: 000001,
...
}
...
}
Эта небольшая программа, чтобы получитьuiDes
, установите шаблон заполнителя<template is="{{uiDes.name}}" data="{{...uiDes}}"/>
. Наконец визуализируйте представление апплета.
В течение всего этого процесса все вашиJS
код работает вReact过程
середина,,JSX
Фрагменты также не получают никакой специальной обработки, простоReact.createElement
вызова, дополнительно из-заReact过程
просто чистыйjs
Операции выполняются очень быстро, обычно всего несколько мс. в конечном итоге выведетuiDes
данные в апплет, апплет передает этоuiDes
Визуализируйте вид.
Теперь мы смотрим на предыдущее заданиеconst b = a
, проблем не будет, потому чтоa
Но обычные предметы. В дополнение к общемуОграничения схемы времени компиляции, например, любая функция, возвращающаяJSX
Фрагменты, динамически генерируемыеJSX
фрагмент,for
перерабатыватьJSX
Фрагменты и т. д. могут быть полностью отброшены, потому чтоJSX
Фрагменты простоjs
объект, вы можете делать все, что хотите, в конце концовReactDOM.render
соберу всеФрагмент результата выполненияизuuid
Определить, сгенерироватьuiDes
, и апплетuiDes
Структура данных отображает окончательный вид.
Можно видеть, что этот новый способ мышления и предыдущийвремя компиляцииЕсть еще большая разница в планах, не так ли?JSX
Сегмент обработки динамический, вы можете делать это где угодно, любая функция любогоJSX
Фрагмент, окончательный результат выполнения будет определять, какой фрагмент отображать, только фрагмент результата выполненияuuid
будет написаноuiDes
. с участиемвремя компиляцииСтатическая идентификация схемы принципиально иная.
Эпилог
«Обсуждение дешево. Покажи мне свой код!» Это просто идея? Или есть уже полная реализация?
полностью реализуется,alitaпроект в процессеJSX
При использовании грамматики эта идея перенимается, что такжеalitaПричина, по которой весь проект React Native можно трансформировать, не ограничивая метод написания, в основном, вдобавокalitaВ этом образе мышления было сделано много оптимизаций. Если вам интересна конкретная реализация этой идеи, вы можете изучить ееalitaИсходный код, это полностью открытый исходный кодGitHub.com/are slabs/Али....
Конечно, вы также можете построить свой собственный, основанный на этой идее.Схема разработки апплета React.