$ npm install react-interact
Containers are higher-order components that communicate with the backend to fetch and mutate data. They pass the data to the wrapped component as props. And they can be configured in various ways so that they know how and where to perform certain CRUD operations.
import React, { Component } from 'react'
import { createContainer } from 'react-interact'
class TodoList extends Component {
render() {
return <div>
{this.props.todos.map(todo => `${todo.title}, `)}
</div>
},
}
export default createContainer(TodoList, () => ({
todos: '/api/v1/todos',
}))
GET /api/v1/todos
[
{id: 1, title: 'Laundry'},
{id: 2, title: 'Weights'},
{id: 3, title: 'Stroke the cat'},
]
Laundry, Weights, Stroke the cat,
Fetching data from the server is an important first step but what do we do about mutating data on the server. For example creating new documents/items or udpating and deleting existing ones.
Interact makes mutations easy by providing wrapped components with an interact
function prop that can be used to send requests to the backend.
import React, { Component } from 'react'
import { createContainer } from 'react-interact'
class TodoList extends Component {
render() {
return (
<div>
{this.props.todos.map(todo => `${todo.title}, `)}
<a onClick={this.handleAddTodo.bind(this)}>Add Todo</a>
</div>
)
},
handleAddTodo() {
this.props.interact.todos.create({})
},
}
export default createContainer(TodoList, () => ({
todos: '/api/v1/todos',
}))
Resources that we defined in our containers can also have subresources.
import React, { Component } from 'react'
import { createContainer } from 'react-interact'
class TodoList extends Component {
render() {
return (
<ul>
{this.props.todos.map(todo => (
<li key={todo.id}>
{todo.title}
<ul>
{todo.subTodos.map(subTodo => (
<li key={subTodo.id}>{subTodo.title}</li>
))}
</ul>
<a
onClick={this.handleAddSubTodo.bind(this, todo.id)}
>
Add SubTodo
</a>
</li>
)}
</ul>
)
},
handleAddSubTodo(id) {
this.props.interact.todos({id}).subTodos.create({})
},
}
export default createContainer(TodoList, ({ id }) => ({
todos: {
base: '/api/v1/todos',
item: `/${id}`,
subs: ({ id }) => ({
subTodos: {
base: '/sub_todos',
item: `/${id}`,
},
}),
},
}))
By default Interact sends HTTP requests using Superagent under the hood but if for example you wish to provide offline-first functionality for your app or you wish to use a different protocol to HTTP you can pass a custom agent/interface to your container that will be the bridge between the frontend and the backend.
This would enable you to use alternatives like PouchDB, another HTTP agent or WebSockets for example.
More info coming soon... See the defaultAgent in the source if you wish to understand better in the meantime.