-
Notifications
You must be signed in to change notification settings - Fork 22
General code guide
Tomas Machalek edited this page Mar 1, 2018
·
7 revisions
- core UI functionality and plug-ins views for general use should be implemented in React
- use TSX
- use functional components if possible; state should present in components representing some high level UI blocks (e.g. a form, result data list etc.).
- generate state by fetching data from stores' getters
- sometimes this is not necessary (e.g. simple flags like "hintVisible?")
- component logic should be based either on SimpleUIModel (legacy one) or StatelessModel<T> (current one).
- please note that while inspired by Flux architectural pattern, both models above violate (in case of SimpleUIModel quite significantly) recommended practices of the pattern:
- async operations are run within models (StatelessModel<T> provides an improved handling of side-effects)
- there are no action creators, actions are typically dispatched directly from React components
- models try to encapsulate whole business logic to avoid Action creator vs. Reducer dilemma known from Redux
- StatelessModel<T> tries to provide best from both (functional vs. object) worlds
- use Immutable.js for storing collections
- please note that while inspired by Flux architectural pattern, both models above violate (in case of SimpleUIModel quite significantly) recommended practices of the pattern:
Make dependencies between objects explicit and as concrete as possible
class Foo {
two:Two;
constructor(one:One) {
// unless you need "one" for other purposes here,
// this is not recommended:
this.two = one.getTwo();
}
}
class Foo {
two:Two;
constructor() {
// This is not recommended as it
// hides the dependency.
this.two = new Two();
}
}
class Foo {
two:Two;
// this is OK
constructor(two:Two) {
this.two = two;
}
}
This should also apply for using page configuration (pages.document.PageModel.getConf()). It is always better to pass miscellaneous configuration values directly rather then passing whole layoutModel (unless you really need its API).
class AHandler {
constructor(canonicalId:string) {
// do stuff
}
}
class MyPage {
private layoutModel:Kontext.PageModel;
private fooHandler:AHandler;
constructor(layoutModel:Kontext.PageModel) {
this.layoutModel = layoutModel;
// we fetch a value from page config:
const cid = this.layoutModel.getConf<Kontext.FullCorpusIdent>('corpusIdent');
// then we pass the value directly
this.fooHandler = new AHandler(cid.canonicalId);
}
}