Сделать и ненужные обратные вызовы создания и назначения (initialState...)?
Я не понимаю, как make
Работа:
let component = ReasonReact.reducerComponent("Greeting");
let make = (~name, _children) => {
...component,
initialState: () => 0, /* here, state is an `int` */
render: (self) => {
let greeting =
"Hello " ++ name ++ ". You've clicked the button " ++ string_of_int(self.state) ++ " time(s)!";
<div>{ReasonReact.stringToElement(greeting)}</div>
}
};
Насколько я понимаю, make
будет вызываться каждый раз, когда <Greeting>
компонент используется в методе рендеринга родительского компонента, поэтому он будет вызываться несколько раз.
Но это также означает, что запись компонента будет создавать initialState
функция правильно?
Я не понимаю, как имеет смысл назначать initialState
некоторые функции каждый раз, когда мы создаем элемент React, при этом он будет вызываться только при подключении элемента и не будет влиять на обновления.
я беру initialState
в качестве примера, но также может сказать то же самое и для других обратных вызовов жизненного цикла.
1 ответ
Насколько я понимаю,
make
будет вызываться каждый раз, когда<Greeting>
компонент используется в методе рендеринга родительского компонента, поэтому он будет вызываться несколько раз.
Да, make
вызывается для каждого рендера.
В этом примереmake Inside
выводится на консоль каждый раз, когда нажимается кнопка - что вызывает новый рендеринг Inside
составная часть.
Мне было любопытно лучше понять, почему это происходит, поэтому делюсь этим здесь на случай, если кому-то еще будет интересно. Реализация работает сегодня примерно так:
<Greeting name="John" />
превращается вReasonReact.element(Greeting.make(~name="John", [||]))
По причине PPX. Вы можете найти реализацию в главном репо Reason.- В этом заявлении
Greeting.make
этоmake
функция, на которую вы ссылаетесь, та же самая функция, которую должен определять каждый компонент ReasonReact. ReasonReact.element
Здесь происходит волшебство. Эта функция будет вызыватьcreateElement
следующим образом ( исходный код):
createElement(
component.reactClassInternal,
~props={"key": key, "ref": ref, "reasonProps": element},
[||]
)
element
прошло как опораreasonProps
на самом деле полный компонент "шаблона", который возвращаетсяmake
(см. назначение несколькими строками выше).component.reactClassInternal
указывает на компонент React, который я буду называтьWiringComponent
для простоты. Что этоWiringComponent
в сущности, объявляет все методы жизненного цикла React и реализует их, просто делегируя фактическое поведение функциям, полученным из "шаблона", объявленного сmake
, Эти функции выбраны изreasonProps
опора, которая передается этомуWiringComponent
, Вы можете увидеть реализацию этого компонента здесь.
Так что, даже если make
вызывается один раз для каждого рендера, как вы упоминаете, в действительности то, что рендерится, является <WiringComponent reasonProps=Greeting.make(...) />
, Тогда, когда WiringComponent.getInitialState
вызывается (только один раз для экземпляра компонента, как обычно), он делегирует этот вызовGreeting.initialState
,
Но это также означает, что запись компонента будет создавать
initialState
функция правильно?
Вот что, похоже, делает код. Решение этой проблемы не кажется мне тривиальным. Учитывая, что помеченные аргументы используются для моделирования компонентов реквизита, нет способа запоминать make
не отказываясь от безопасности типов, так как может быть много "разновидностей" этой функции (по одному для каждого компонента).