View Module
We can be used to implement a module with a View by inheriting the ViewModule
and defining the component
method (a React function component).
It is possible to inject any method of the current ViewModule
in its component
, and also to inject the current shared module state or other dependent module state using useConnector:
interface Todo {
text: string;
completed: boolean;
}
@injectable()
class TodoView extends ViewModule {
@state
list: Todo[] = [];
addTodo(text: string) {
this.list.push({
text,
completed: false,
});
}
@action
toggleTodo(key: number, value: boolean) {
this.list[key].completed = !value;
}
component() {
const list = useConnector(() => this.list);
return (
<ul>
{this.list.map(({ text, completed }, key) => (
<li key={key} onClick={() => this.toggleTodo(key, completed)}>
{text}
</li>
))}
</ul>
);
}
}
useConnector
also supports returning a state object, which automatically makes shallow comparisons:
const { list, visibilityFilter } = useConnector(() => ({
list: this.list,
visibilityFilter: this.visibilityFilter,
}));
It should be noted that while the ViewModule
supports inheritance, function components based on component
method implementations must be called in the same way as components based on superclass component
methods, not using the jsx:
@injectable()
class BaseFooView extends ViewModule {
component() {
return <span>foo</span>;
}
}
class FooView extends BaseFooView {
component() {
return (
<>
<span>foo</span>
{
super.component()
// Don't make it: <super.component />
}
</>
);
}
}