Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/joshnuss/glue
React hook for server-side state
https://github.com/joshnuss/glue
elixir erlang phoenix react websocket
Last synced: 3 months ago
JSON representation
React hook for server-side state
- Host: GitHub
- URL: https://github.com/joshnuss/glue
- Owner: joshnuss
- Created: 2019-08-15T02:31:32.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T07:46:50.000Z (about 2 years ago)
- Last Synced: 2024-10-14T22:21:37.887Z (4 months ago)
- Topics: elixir, erlang, phoenix, react, websocket
- Language: JavaScript
- Homepage:
- Size: 1.38 MB
- Stars: 17
- Watchers: 3
- Forks: 1
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Easy server-side state with React & Phoenix
React is great at rendering HTML, but sharing state can be tricky.
One technology that is designed for managing large amounts of shared state is the [Actor Model](https://en.wikipedia.org/wiki/Actor_model), known in Erlang as `GenServer`.
By relying on Erlang for state management, it frees us from needing to write boilerplate Redux, hooks and/or GraphQL/REST wrappers and just write GenServer code. The React hooks and Websocket code is then generated for you.
[View live demo](http://react-use-server-state.gigalixirapp.com/)
## Counter Example
Let's take the example of a simple counter. This is what it looks like with React's `useState()` hook:
```js
import React, {useState} from 'react'export default function() {
const [count, set] = useState(0)return (
set(count + 1)}>-
set(count - 1)}>+
{count}
)
}
```Instead of storing state in the local browser's memory with `useState()`, we can switch to server-side state by simply swapping `useState()` to `useServerState()`:
```js
import React from 'react'
import {useServerState} from '@glue/react'export default function() {
const {count, increment, decrement} = useServerState('counter', {sync: true})
return (
decrement()}>-
increment()}>+
{count}
)
}
```The state will first be queried from the server. Subsequent changes will be synced back to the server and then between all connected users via Websockets.
Now we just need to define a `GenServer` to hold the state in the backend:
```elixir
defmodule Counter do
use Agent@name :counter
def start_link(_opts),
do: Agent.start_link(fn -> 0 end, name: @name)def get(), do: Agent.get(@name, & &1)
def increment(), do: apply(+1)
def decrement(), do: apply(-1)defp apply(delta) do
Agent.get_and_update(@name, &{&1 + delta, &1 + delta})
end
end
```That's it! Just `GenServer`'s and pure JSX components.
![Counter example](/counter-example.gif)
### This is alpha software.