Skip to content

Commit

Permalink
doc: Update example code of lifecycle to show as tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
CarLeonDev committed Jun 23, 2024
1 parent 2955abe commit c8e7820
Show file tree
Hide file tree
Showing 18 changed files with 543 additions and 160 deletions.
238 changes: 79 additions & 159 deletions website/src/content/docs/core_concepts/lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@ description: The lifecycle of a component in React.
sidebar:
order: 5
---
import { HE, HM, HT } from '@/components/Highlight';
import { HE, HM, HT, HS } from '@/components/Highlight';
import { Code } from "@astrojs/starlight/components";
import counterViewCode from '@/examples/counter/lib/counter_view.dart?raw';
import counterMainCode from '@/examples/counter/lib/main.dart?raw';
import { Tabs, TabItem } from "@/components/Tabs";
import ZappButton from "@/components/ZappButton.astro";
import { marks } from '@/examples/marks.ts'
import TipLifecycleExample from '@/content/docs/shareds/tip_lifecycle_example.mdx';
import { counterViewMark } from '@/examples/counter/marks.ts';

import counterControllerEventHandlerCode from '@/examples/lifecycle_event_handler/lib/counter_controller.dart?raw';
import counterEventHandlerCode from '@/examples/lifecycle_event_handler/lib/counter.dart?raw';
import counterViewEventHandlerCode from '@/examples/lifecycle_event_handler/lib/counter_view.dart?raw';
import counterMainEventHandlerCode from '@/examples/lifecycle_event_handler/lib/main.dart?raw';

import counterControllerLifecycleObserverCode from '@/examples/lifecycle_observer/lib/counter_controller.dart?raw';
import counterLifecycleObserverCode from '@/examples/lifecycle_observer/lib/counter.dart?raw';
import counterViewLifecycleObserverCode from '@/examples/lifecycle_observer/lib/counter_view.dart?raw';
import counterMainLifecycleObserverCode from '@/examples/lifecycle_observer/lib/main.dart?raw';

import counterControllerLifecycleUseEffectCode from '@/examples/lifecycle_use_effect/lib/counter_controller.dart?raw';
import counterLifecycleUseEffectCode from '@/examples/lifecycle_use_effect/lib/counter.dart?raw';
import counterViewLifecycleUseEffectCode from '@/examples/lifecycle_use_effect/lib/counter_view.dart?raw';
import counterMainLifecycleUseEffectCode from '@/examples/lifecycle_use_effect/lib/main.dart?raw';

In Reactter, both the states and the dependency (managed by the [dependency injection](/reactter/core_concepts/dependency_injection)) contain different stages,
also known as <HT><a href="https://pub.dev/documentation/reactter/latest/reactter/Lifecycle.html" target="_blank">`Lifecycle`</a></HT>.
The lifecycle entails events emitted through the [event handler](/reactter/core_concepts/event_handler).
Expand All @@ -34,93 +50,29 @@ You can listen to the lifecycle events of a dependency by using <HM>`Reactter.on

<TipLifecycleExample />

```dart title="counter_controller.dart" "Reactter.on" "Lifecycle.willMount" "Lifecycle.didMount" "Lifecycle.willUpdate" "Lifecycle.didUpdate" "Lifecycle.willUnmount" "Lifecycle.didUnmount"
import 'package:reactter/reactter.dart';
class CounterController extends Reactter {
final count = Signal(0);
counter() {
Reactter.on(this, Lifecycle.willMount, (_, __) {
print('Counter will mount');
});
Reactter.on(this, Lifecycle.didMount, (_, __) {
print('Counter mounted');
});
Reactter.on(this, Lifecycle.willUpdate, (_, state) {
print('Counter will update by $state');
});
Reactter.on(this, Lifecycle.didUpdate, (_, state) {
print('Counter did update by $state');
});
Reactter.on(this, Lifecycle.willUnmount, (_, __) {
print('Counter will unmount');
});
Reactter.on(this, Lifecycle.didUnmount, (_, __) {
print('Counter did unmount');
});
}
void increment() {
count.value++;
}
void decrement() {
count.value--;
}
}
```

<Code title="counter_view.dart" code={counterViewCode} lang="dart" mark={counterViewMark} collapse={["1-100"]} />

```dart title="main.dart" "Reactter.on" "ReactterDependency" "Lifecycle.unregistered" "Lifecycle.registered" "Lifecycle.initialized" "Lifecycle.destroyed" /(Counter)\\>/
import 'package:flutter/material.dart';
import 'package:reactter/reactter.dart';
import 'counter_view.dart';
import 'counter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Reactter.on(
ReactterDependency<CounterController>(),
Lifecycle.unregistered,
(_, __) => print('Counter unregistered'),
);
Reactter.on(
ReactterDependency<CounterController>(),
Lifecycle.registered,
(_, __) => print('Counter registered'),
);
Reactter.on(
ReactterDependency<CounterController>(),
Lifecycle.initialized,
(_, __) => print('Counter initialized'),
);
Reactter.one(
ReactterDependency<CounterController>(),
Lifecycle.destroyed,
(_, __) => print('Counter destroyed'),
);
return MaterialApp(
home: CounterControllerApp(),
);
}
}
```
<div class="code-tabs">
<ZappButton path="examples/lifecycle_event_handler"/>

<Tabs>
<TabItem>
<HM single slot="label">counter_view.dart</HM>
<Code code={counterViewEventHandlerCode} lang="dart" collapse={["34-60"]} mark={[...marks, {range: "11-15"}, {range: "17-21"}, {range: "23-27"}, {range: "29-33"}]} />
</TabItem>

<TabItem>
<HM single slot="label">counter_controller.dart</HM>
<Code code={counterControllerEventHandlerCode} lang="dart" mark={[...marks, {range: "7-9"}, {range: "11-13"}, {range: "15-17"}, {range: "19-21"}, {range: "23-25"}, {range: "27-29"}]}/>
</TabItem>

<TabItem label="counter.dart">
<Code code={counterEventHandlerCode} lang="dart" mark={marks} />
</TabItem>

<TabItem label="main.dart">
<Code code={counterMainEventHandlerCode} lang="dart" mark={marks} />
</TabItem>
</Tabs>
</div>

:::note
The <HT>`ReactterDependency`</HT> is a generic class that takes the type of the dependency and optionally pass an `id`.
Expand All @@ -135,86 +87,54 @@ and use its methods to observe the lifecycle events. e.g:

<TipLifecycleExample />

```dart title="counter_controller.dart" "LifecycleObserver" "onInitialized" "onDidMount" "onWillMount" "onWillUpdate" "onDidUpdate" "onWillUnmount" "onDidUnmount"
import 'package:reactter/reactter.dart';
class CounterController extends LifecycleObserver {
final count = Signal(0);
void onInitialized() {
print('Counter initialized');
}
<div class="code-tabs">
<ZappButton path="examples/lifecycle_observer"/>

void onDidMount() {
print('Counter mounted');
}
<Tabs>
<TabItem>
<HM single slot="label">counter_controller.dart</HM>
<Code code={counterControllerLifecycleObserverCode} lang="dart" mark={[...marks, {range: "6-8"}, {range: "10-12"}, {range: "14-16"}, {range: "18-20"}, {range: "22-24"}, {range: "26-28"}, {range: "30-32"}]}/>
</TabItem>

void onWillMount() {
print('Counter will mount');
}
<TabItem label="counter_view.dart">
<Code code={counterViewLifecycleObserverCode} lang="dart" mark={marks} />
</TabItem>

void onWillUpdate(ReactterState state) {
print('Counter will update by $state');
}
<TabItem label="counter.dart">
<Code code={counterLifecycleObserverCode} lang="dart" mark={marks} />
</TabItem>

void onDidUpdate(ReactterState state) {
print('Counter did update by $state');
}
void onWillUnmount() {
print('Counter will unmount');
}
void onDidUnmount() {
print('Counter did unmount');
}
void increment() {
count.value++;
}
void decrement() {
count.value--;
}
}
```

<Code title="counter_view.dart" code={counterViewCode} lang="dart" mark={counterViewMark} collapse={["1-100"]} />

<Code title="main.dart" code={counterMainCode} lang="dart" collapse={["1-100"]} />
<TabItem label="main.dart">
<Code code={counterMainLifecycleObserverCode} lang="dart" mark={marks} />
</TabItem>
</Tabs>
</div>

## Using UseEffect

The <HT>`UseEffect`</HT> hook can be used to listen to the lifecycle events of a dependency. e.g:
The <HT>[`UseEffect`](/reactter/hooks/use_effect)</HT> hook can be used to listen to the lifecycle events of a dependency. e.g:

<TipLifecycleExample />

```dart title="counter.dart" "UseEffect" /(count)(?!\u0060)/
import 'package:reactter/reactter.dart';
class Counter extends Reactter {
final count = Signal(0);
const Counter() {
UseEffect(() {
print('Counter mounted(`Lifecycle.didMount`)');
return () {
print('Counter will unmount(`Lifecycle.willUnmount`)');
};
}, []);
}
<div class="code-tabs">
<ZappButton path="examples/lifecycle_use_effect"/>

void increment() {
count.value++;
}
<Tabs>
<TabItem>
<HM single slot="label">counter_controller.dart</HM>
<Code code={counterControllerLifecycleUseEffectCode} lang="dart" mark={[...marks, {range: "7-13"}, {range: "15-19"}]}/>
</TabItem>

void decrement() {
count.value--;
}
}
```
<TabItem label="counter_view.dart">
<Code code={counterViewLifecycleUseEffectCode} lang="dart" mark={marks} />
</TabItem>

<Code title="counter_view.dart" code={counterViewCode} lang="dart" mark={counterViewMark} collapse={["1-100"]} />
<TabItem label="counter.dart">
<Code code={counterLifecycleUseEffectCode} lang="dart" mark={marks} />
</TabItem>

<Code title="main.dart" code={counterMainCode} lang="dart" collapse={["1-100"]} />
<TabItem label="main.dart">
<Code code={counterMainLifecycleUseEffectCode} lang="dart" mark={marks} />
</TabItem>
</Tabs>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ Let's create a simple counter app using Reactter to demonstrate how to control t
</Tabs>
</div>


Now, when you run the app, you will see a counter app with two buttons to increment and decrement the `count` value.

In this scenario, only the <HT>`Text`</HT> widget will be rebuilt when the `count` value changes, not the entire <HT>`CounterView`</HT> widget.
Expand Down
41 changes: 41 additions & 0 deletions website/src/examples/lifecycle_event_handler/lib/counter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_reactter/flutter_reactter.dart';

import 'counter_controller.dart';

class Counter extends StatelessWidget {
const Counter({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
// Provides the `CounterController` dependency to the widget tree
return ReactterProvider<CounterController>(
() => CounterController(),
builder: (context, counterController, child) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: counterController.decrement,
child: const Icon(Icons.remove),
),
const SizedBox(width: 8),
// Observes the `count` property of the `counterController`
// and rebuilds the widget tree when the `count` value changes
ReactterConsumer<CounterController>(
listenStates: (counterController) => [counterController.count],
builder: (context, counterController, child) {
return Text("${counterController.count}");
},
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: counterController.increment,
child: const Icon(Icons.add),
),
],
);
},
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:flutter_reactter/flutter_reactter.dart';

class CounterController {
final count = Signal(0);

CounterController() {
Reactter.on(this, Lifecycle.willMount, (_, __) {
print('CounterController will mount');
});

Reactter.on(this, Lifecycle.didMount, (_, __) {
print('CounterController did mount');
});

Reactter.on(this, Lifecycle.willUpdate, (_, state) {
print('CounterController will update by ${state.runtimeType}');
});

Reactter.on(this, Lifecycle.didUpdate, (_, state) {
print('CounterController did updated by ${state.runtimeType}');
});

Reactter.on(this, Lifecycle.willUnmount, (_, __) {
print('CounterController will unmount');
});

Reactter.on(this, Lifecycle.didUnmount, (_, __) {
print('CounterController did unmount');
});
}

void increment() {
count.value++;
}

void decrement() {
count.value--;
}
}
Loading

0 comments on commit c8e7820

Please sign in to comment.