Skip to content
This repository has been archived by the owner on Sep 3, 2022. It is now read-only.

[question] use with other libraries #2

Open
brodybits opened this issue Sep 16, 2019 · 9 comments
Open

[question] use with other libraries #2

brodybits opened this issue Sep 16, 2019 · 9 comments

Comments

@brodybits
Copy link
Contributor

brodybits commented Sep 16, 2019

such as:

  • react-primitives (which enables use with React Native)
  • http://grommet.io (which seems to have a hard dependency on React, assuming nobody ports it out or or adds some kind of an abstraction layer)

and some native view frameworks from #3:

@brodybits brodybits changed the title [...] use with other libraries [??] use with other libraries Sep 16, 2019
@rbiggs
Copy link
Contributor

rbiggs commented Sep 16, 2019

Composi shares some features externally with React because of the use of JSX. This provides JSX features such as props to pass data down like in React. It has a virtual DOM as well with a reconciliation (diffing) algorithm. Composi lacks class components. It has function components, but with a twist. They support lifecycle hooks similar to the ones React class components have. But they are implemented at the element level. Composi lifecycle hooks are for tracking lifecycle of an element in a component--not the component itself. This makes sharing components and other features between React and Composi fundamentally challenging. Also Composi uses a state management system derived from the Elm Architecture, which is simpler than the React/Redux duopoly.
I have looked at NativeScript in the past. Since it supports vanilla JavaScript, you should be able to use that with Composi. To be honest, I haven't had the motivation to dig too deeply into it. It would probably be better to create a wrapper for NativeScript like the Angular and Vue ones that would allow Composi's state management to trigger updates automatically in NativeScript.
To pull of NativeScript support I'd need help from somebod(y/ies) with some experience and familiarity with it.

@brodybits
Copy link
Contributor Author

Makes sense, thanks. A couple more thoughts that are likely going off-topic:

  • I wonder if it would be interesting to make more abstract API layers so that people like me can get the benefits on React Native or Grommet which are built on React?
  • I wonder if "lifecycle hooks" should be documented as just a special category of events?

@rbiggs
Copy link
Contributor

rbiggs commented Sep 17, 2019

Well, technically lifecycle hooks are not events. That's why I call them hooks. The just look like events due to the React precedence. They are actually just JSX attributes that exist on the virtual nodes. They never become anything real in the real DOM.

You mention "make more abstract API layers". I suppose you're talking about Composi? If so, the state management runtime is already quite agnostic. The render function just passes state to whatever you want to use to render it with. By default Composi uses its own render function, but you could use it for React, Vue, or whatever. Here is an example of Composi state management using React to render a function component that uses React hooks (useEffect):

import React from 'react';
import { render } from './utils'
import { run } from '@composi/core'
import { List } from './components/list'
import { actions } from './effects/actions'
import { batchedSubscriptions } from './effects/subscriptions'

const program = {
  init() {
    return [null]
  },
  view(state, send) {
    return state && render(<List {...{state, send}} />, 'section');
  },
  update(state, msg, send) {
    return actions(state, msg, send)
  },
  subscriptions(state, send) {
    return batchedSubscriptions
  }
}

run(program)

@brodybits
Copy link
Contributor Author

By default Composi uses its own render function, but you could use it for React, Vue, or whatever.

+1, wouldn't mind some more documentation on this

Here is an example of Composi state management using React to render a function component that uses React hooks
[...]

Is there an example somewhere?

I would like to take a look at this kind of thing, may give it a try with React Native.

@rbiggs
Copy link
Contributor

rbiggs commented Sep 17, 2019

OK, just uploaded this project: https://github.com/composi/list-react

It was created with create-react-app. I added Composi as a dependency. The components are React 16 functional components using React hooks. It has a Composi program that uses Composi's run function to create state management, which is handled with actions and effects, etc. The program's view method uses React's render method to render the React component when state changes. The React components are sending messages just like Composi components would. These get processed by the Composi program's update method. Just look at the src/index.js file to see how the two work together.

@rbiggs
Copy link
Contributor

rbiggs commented Sep 17, 2019

When this project first runs, a subscription launches that fetches initial data from a JSON file in the public/data folder. It also uses the Composi module @composi/idb, which is a simple promise-based wrapper I made for IndexedDB. This makes using IndexedDB as easy as using localStorage. I use @composi/idb to persist data locally when the user adds or deletes items. Add some items. The reload the browser or quite the browser and relaunch it. You'll see the new items have indeed been saved to IndexedDB. To handle fetching and persisting data there are new messages: useFetchedData and saveLocally, and corresponding actions to handle these. Hope that makes it clear what's going on in this project for you.

@rbiggs
Copy link
Contributor

rbiggs commented Sep 17, 2019

By the way, this project is basically the same as the full Composi project: https://github.com/composi/examples/tree/master/2-complex%20projects/4-todo-list. The Composi project has a total JavaScript payload of 23KB minified. This React version has a total JavaScript payload of 126KB minified.

@brodybits brodybits changed the title [??] use with other libraries [question] use with other libraries Sep 18, 2019
@brodybits
Copy link
Contributor Author

Thanks @rbiggs. I gave it a try yesterday, had some trouble porting to React Native since it seem to use very modular CSS. I hope to take another look, someday.

@rbiggs
Copy link
Contributor

rbiggs commented Nov 17, 2019

As an update to this issue, I've created a version of @composi/core that is just the state manage, along with tagged unions and batched effects.It weighs in a about 600 kb. It's available from npm:

npm I -D @composi/runtime

Github repo: https://github.com/composi/runtime

You can use React as the render, as in this repo: https://github.com/composi/list-react
And here's an example of @composi/runtime with Lit-Html: https://github.com/composi/list-lit-html

Documentation is the same as regular runtime of @composi/core: https://composi.github.io/en/docs/runtime/runtime.html

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants