-
Notifications
You must be signed in to change notification settings - Fork 1
Component lifecycle
Syone edited this page Mar 7, 2025
·
4 revisions
This is what happens when we render (echo) a component
graph TD;
Init([Construct and render]) --> A[Added] --> B[Mount] --> C(Render sub components) --> D[Mounted] --> E(Render current component);
We can add hooks that are called during different moments at component rendering process:
- Added event: when a component is added into another
- Mount event: before the rendering of sub components
- Mounted event: after the rendering of sub components
The Component class has 3 methods for registering callbacks for these events:
added(callable $callback)
mount(callable $callback)
mounted(callable $callback)
Example:
<?php
use Sy\Component;
class A extends Component {
public function __construct() {
echo 'A Construct' . PHP_EOL;
$this->mounted(function () {
echo 'A Mounted' . PHP_EOL;
});
$this->mount(function () {
echo 'A Mount' . PHP_EOL;
$this->setVar('SLOT', new B());
});
$this->added(function () {
echo 'A Added' . PHP_EOL;
});
}
public function __toString() {
echo 'A Render start' . PHP_EOL;
$res = parent::__toString();
echo 'A Render end' . PHP_EOL;
return $res;
}
}
class B extends Component {
public function __construct() {
echo 'B Construct' . PHP_EOL;
$this->mounted(function () {
echo 'B Mounted' . PHP_EOL;
});
$this->mount(function () {
echo 'B Mount' . PHP_EOL;
});
$this->added(function () {
echo 'B Added' . PHP_EOL;
});
}
public function __toString() {
echo 'B Render start' . PHP_EOL;
$res = parent::__toString();
echo 'B Render end' . PHP_EOL;
return $res;
}
}
echo new A();
Will result:
A Construct
A Render start
A Added
A Mount
B Construct
B Added
B Render start
B Mount
B Mounted
B Render end
A Mounted
A Render end
As a best practice, we recommend to make all the "setVar" stuff during the mount stage. Then we ensure that all the parent component translators at transmitted before calling the translation method (underscore):
<?php
use Sy\Component;
class MyComponent extends Component {
public function __construct() {
$this->addTranslator(__DIR__ . '/lang');
$this->setTemplateFile(__DIR__ . '/mycomponent.tpl');
$this->mount(fn() => $this->init());
}
private function init() {
$this->setVars([
'HELLO' => $this->_('hello'),
'WORLD' => $this->_('world'),
'COMP_SLOT' => new MyOtherComponent(),
]);
}
}
class MyOtherComponent extends Component {
public function __construct() {
$this->setTemplateFile(__DIR__ . '/myothercomponent.tpl');
//!\\ Be careful here, 'hello' can not be translated with the translator of MyComponent because it is not transmitted yet at the construction stage
$this->setVar('HELLO' => $this->_('hello'));
$this->mount(fn() => $this->init());
}
private function init() {
$this->setVar('WORLD' => $this->_('world'));
}
}