Skip to content

Commit

Permalink
Add example with-xstate (#10234)
Browse files Browse the repository at this point in the history
Co-authored-by: Joe Haddad <timer150@gmail.com>
  • Loading branch information
rohmanhm and Timer committed Jan 23, 2020
1 parent c1cbad0 commit 320d98e
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 0 deletions.
46 changes: 46 additions & 0 deletions examples/with-xstate/README.md
@@ -0,0 +1,46 @@
# XState example

This example shows how to integrate XState in Next.js. For more info about XState you can visit [here](https://xstate.js.org/).

## Deploy your own

Deploy the example using [ZEIT Now](https://zeit.co/now):

[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/next.js/tree/canary/examples/with-xstate)

## How to use

### Using `create-next-app`

Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npm init next-app --example with-xstate with-xstate-app
# or
yarn create next-app --example with-xstate with-xstate-app
```

### Download manually

Download the example:

```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-xstate
cd with-xstate
```

Install it and run:

```bash
npm install
npm run dev
# or
yarn
yarn dev
```

Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)):

```bash
now
```
10 changes: 10 additions & 0 deletions examples/with-xstate/components/Counter.js
@@ -0,0 +1,10 @@
export default ({ counter = {} }) => (
<div>
<h1>
Count: <span>{counter.count}</span>
</h1>
<button onClick={() => counter.decrement()}>-1</button>
<button onClick={() => counter.increment()}>+1</button>
<button onClick={() => counter.reset()}>Reset</button>
</div>
)
14 changes: 14 additions & 0 deletions examples/with-xstate/components/Toggle.js
@@ -0,0 +1,14 @@
import React from 'react'

const Toggle = ({ onToggle, active }) => {
return (
<div>
<h1>
Toogle status: <span>{active ? 'On' : 'Off'}</span>
</h1>
<button onClick={onToggle}>Toggle</button>
</div>
)
}

export default Toggle
4 changes: 4 additions & 0 deletions examples/with-xstate/components/index.js
@@ -0,0 +1,4 @@
import Counter from './Counter'
import Toggle from './Toggle'

export { Counter, Toggle }
20 changes: 20 additions & 0 deletions examples/with-xstate/machines/counterMachine.js
@@ -0,0 +1,20 @@
import { Machine, assign } from 'xstate'

const increment = context => context.count + 1
const decrement = context => context.count - 1

export const counterMachine = Machine({
initial: 'active',
context: {
count: 0,
},
states: {
active: {
on: {
INC: { actions: assign({ count: increment }) },
DEC: { actions: assign({ count: decrement }) },
RESET: { actions: assign({ count: 0 }) },
},
},
},
})
14 changes: 14 additions & 0 deletions examples/with-xstate/machines/toggleMachine.js
@@ -0,0 +1,14 @@
import { Machine } from 'xstate'

export const toggleMachine = Machine({
id: 'toggle',
initial: 'inactive',
states: {
inactive: {
on: { TOGGLE: 'active' },
},
active: {
on: { TOGGLE: 'inactive' },
},
},
})
17 changes: 17 additions & 0 deletions examples/with-xstate/package.json
@@ -0,0 +1,17 @@
{
"name": "with-xstate",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@xstate/react": "0.8.1",
"next": "latest",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"xstate": "4.7.6"
},
"license": "ISC"
}
36 changes: 36 additions & 0 deletions examples/with-xstate/pages/index.js
@@ -0,0 +1,36 @@
import React from 'react'
import { useMachine } from '@xstate/react'
import { Counter, Toggle } from '../components'
import { toggleMachine } from '../machines/toggleMachine'
import { counterMachine } from '../machines/counterMachine'

const IndexPage = ({ count }) => {
const [toggleCurrent, toggleSend] = useMachine(toggleMachine)
const [counterCurrent, counterSend] = useMachine(counterMachine, {
context: { count },
})

return (
<div>
<Counter
counter={{
count: counterCurrent.context.count,
increment: () => counterSend('INC'),
decrement: () => counterSend('DEC'),
reset: () => counterSend('RESET'),
}}
/>
<hr />
<Toggle
onToggle={() => toggleSend('TOGGLE')}
active={toggleCurrent.matches('active')}
/>
</div>
)
}

IndexPage.getInitialProps = async () => {
return { count: 999 }
}

export default IndexPage

0 comments on commit 320d98e

Please sign in to comment.