1

I'm new to om.next (and to clojurescript), and I have the following question. I can only get the root component to be invoked with the reconciler (i.e. have its query method invoked); every other component seems to need to be invoked with props and with om/factory. I think I'm missing something.

I am attempting to create a todo list app (100 points for originality!), with a filter to show completed/incomplete/all items. If my TodoList component is the root component, I can invoke it with query: [:todos] with no problem. I'd like to have a different root component, and also have a Filter component that goes through the reconciler.

Possible options I can see:

  • have multiple om/add-root! calls (this prevents us from having nested components that use the reconciler, and is not the pattern that I see in tutorials)

  • wrap everything in a global component and pass state down through props. But the examples make read a multimethod, which doesn't jive with this approach.

Is this possible? Thank you!

Robert Balicki
  • 1,583
  • 2
  • 16
  • 24

2 Answers2

1

The concept behind Om Next (and others such as reframe) is that there is one source of truth - your app state. With Om Next the UI of your application is made up of one (upside down) component tree. During rendering your app state is loaded into your Root component by Om Next interpreting its static query. This app state is received as 'props'. It is your job to pick these props apart and hand 'sub props' down the rest of the tree. You do this in the render method of each of your components.

So your second option is the way to go. reads are related to keywords that are in your static component queries. If you make sure that your state is in default db format, then in fact every read can be implemented the same way, making use of db->tree. Having a global component and making every read a multimethod are unrelated concepts, and thus not incompatible. In fact having both is quite idiomatic.

There are ToDo application examples already that you may wish to look at for reference: here and here.

One thing to note is that your Root component query will use joins to include the other components, so your query [:todos] does not look right to me. Something like [{:todos (om/get-query TodoList)}] would be better :-)

Chris Murphy
  • 6,411
  • 1
  • 24
  • 42
1

If you haven't already please take a look at Components, Identity & Normalization · omcljs/om Wiki · GitHub. This tutorial shows how to organize a multi-component application under a single root - and it should also make clear how read, mutate, Ident, IQuery, etc. are being used by each individual component to coordinate interaction with the one-and-only app state via the reconciler. The app-state is basically the application's database - using nested data structures inside a single Map.

React applications typically only have a single root component - if there are multiple roots they are typically organized by routes, i.e. one root per route (see also Top-level React Components — Medium).

Also: Om/Next: The Reconciler — Medium

Peer Reynders
  • 546
  • 3
  • 6