├── .gitignore ├── README.md ├── components ├── LocalCounter.js ├── MessageInput.js ├── Nav.js └── PageWrapper.js ├── package.json ├── pages ├── index.js └── other.js ├── store.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nextjs and Freactal Example 2 | 3 | This example demonstrates the use of [freactal](https://github.com/FormidableLabs/freactal#freactal) with [Nextjs](https://github.com/zeit/next.js). 4 | 5 | The example is just a counter that maintains state between pages. 6 | 7 | Each page is wrapped with state for globally accessible state values. For local needs, state can be composed and the state needed at lower levels can be specified in their own store and composed. If you look at the `LocalCounter` component, you'll see that it has its own state, but also has access to the global state through its parent. The local state can be updated, but leaving the page and coming back reinitializes the local state, which leaving the global state untouched, just like we want. 8 | -------------------------------------------------------------------------------- /components/LocalCounter.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { provideState, injectState, softUpdate } from 'freactal' 3 | 4 | const stateInitializer = { 5 | initialState: () => ({ localCounter: 0 }), 6 | effects: { 7 | localAddOne: softUpdate(state => ({ localCounter: state.localCounter + 1 })) 8 | } 9 | } 10 | 11 | const wrapInState = provideState(stateInitializer) 12 | 13 | export default wrapInState(injectState(({state, effects}) => { 14 | const handleInput = (evt) => effects.updateMessage(evt.target.value) 15 | return ( 16 |
17 |
18 | Parent Counter Value: {state.counter} 19 |
20 | 21 |
22 |
23 | Local count: {state.localCounter} 24 |
25 | 26 |
27 |
28 | ) 29 | })) 30 | -------------------------------------------------------------------------------- /components/MessageInput.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { provideState, injectState, softUpdate } from 'freactal' 3 | 4 | const stateInitializer = { 5 | initialState: () => ({ message: 'testing' }), 6 | effects: { 7 | updateMessage: softUpdate((state, val) => ({message: val})) 8 | } 9 | } 10 | 11 | const wrapInState = provideState(stateInitializer) 12 | 13 | export default wrapInState(injectState(({state, effects}) => { 14 | const handleInput = evt => effects.updateMessage(evt.target.value) 15 | return ( 16 |
17 |

{state.message}

18 | 19 |
20 | ) 21 | })) 22 | -------------------------------------------------------------------------------- /components/Nav.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Link from 'next/link' 3 | 4 | export default (props) => ( 5 |
6 | Home{' '} 7 | Other 8 |
9 | ) 10 | -------------------------------------------------------------------------------- /components/PageWrapper.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default ({children}) => ( 4 |
5 | {children} 6 |
7 | ) 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "freactal-next", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "next", 8 | "build": "next build", 9 | "start": "next start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "repository": {}, 15 | "dependencies": { 16 | "freactal": "^1.0.0", 17 | "next": "^2.3.1", 18 | "ramda": "^0.23.0", 19 | "react": "^15.5.4", 20 | "react-dom": "^15.5.4" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import Nav from '../components/Nav' 3 | import PageWrapper from '../components/PageWrapper' 4 | import withState from '../store' 5 | import LocalCounter from '../components/LocalCounter' 6 | 7 | export default withState(({state, effects}) => ( 8 | 9 |