marsdb-react
v0.1.4
Published
Declarative data-binding for React based on MarsDB
Downloads
11
Maintainers
Readme
MarsDB-React
Declarative data-binding for React based on MarsDB, inspired by Relay, Redux, Flux and Mithril.
- Declarative: Never again communicate with your data store using an imperative API. Simply declare your data requirements with flexible MarsDB cursors
- Colocation: Queries live next to the views that rely on them, so you can easily reason about your app.
- Mongo-like queries/mutations: Work with the data as always, MarsDB takes care of the rest.
Example
Basic concepts
MarsDB-React uses Relay-like concept of data reuirements declaration. Just make a component and create a data container below based on the component.
import React from 'react';
import ReactDOM from 'react-dom';
import { createContainer, DataManagerContainer } from 'marsdb-react';
import Collection from 'marsdb';
const MessageModel = new Collection('messages');
class HelloWorld extends React.Component {
handleClickAddMessage = () => {
MessageModel.insert({ text: this.state.text });
this.setState({ text: '' });
};
handleChangeText = (e) => {
this.setState({ text: e.target.value });
};
handleClickMoreLimit = () => {
const { limit } = this.props.variables;
limit(10 + limit());
};
render() {
const { messages, variables } = this.props;
const { limit } = variables;
return (
<div>
<div>
<h3>Add a message</h3>
<input
placeholder="Message text"
value={this.state.text}
onChange={this.handleChangeText}
/>
<button onClick={this.handleClickAddMessage}>Say "hello"</button>
</div>
<div>
<h3>Messages (with limit: {limit()})</h3>
<div><button onClick={this.handleClickMoreLimit}>Limit +10</button></div>
{messages().map(m => (
<p key={m()._id}>"Hello" with message: {m().text}!</p>
))}
</div>
</div>
);
}
}
HelloWorld = createContainer(HelloWorld, {
initialVariables: {
limit: 2
},
fragments: {
messages: ({limit}) => MessageModel.find().limit(limit())
}
});
ReactDOM.render(document.body, (
<DataManagerContainer
component={HelloWorld}
renderLoading(() => <span>Loading...</span>)
/>
))
As you can see, data declaration uses the same fields, that Relay use. But it's plain javascript! There is some things, that should be noticed:
- Variables in fragment function and in a component, data from props in a component – all is a getter-setter property functions. By calling
limit()
it returns current value, by callinglimit(10)
it sets new one and returns 10. - Each property have a
version
variable, that changed when new value is set. It can be used inshouldComponentUpdate
- As we noticed above, each data property is a getter-setter property function. To access a messages list you need to call
messages()
that returns current list of messages. Each message of the list is also a proprty function! - Each change of the model automatically triggers re-rendering of the component with new data. No subsribers, no listeners, no special "mutation" logic. Just insert/update.
- Data container can be rendered by
<DataManagerContainer>
component. It resolves all data requests and show a component only when all data received and ready to show. - To use MarsDB-React with React Router use MarsDB-React-Router
- For more complex example, see TodoMVC
- If you have any questions, please ask me by issue
TodoMVC
The repository comes with an implementation of TodoMVC. To try it out:
git clone https://github.com/c58/marsdb-react.git
cd marsdb-react/examples/todomvc && npm install
npm start
Then, just point your browser at http://localhost:3000
.
Contributing
I’m waiting for your pull requests and issues.
Don’t forget to execute gulp lint
before requesting. Accepted only requests without errors.
License
See License