Skip to content

Commit

Permalink
Merge pull request #9 from andrejewski/bare-init
Browse files Browse the repository at this point in the history
React init aligns with runtime init
  • Loading branch information
andrejewski authored Aug 15, 2017
2 parents 890d447 + 3d87589 commit 57aa624
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 52 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ npm install raj

#### Integrations
- `raj/react`: React bindings
- `program(Component, {init, update, view})`: create a React program
- `program(Component, props => ({init, update, view}))`: create a React program
- `Component`: a React Component class
- `init(props)`: return the initial state and optional effect
- `props`: the React component `props`
- `init`: the initial state and optional effect
- `update(message, state)`: return the new state and optional effect
- `view(state, dispatch)`: return the React view

Expand All @@ -37,7 +38,7 @@ The view and any side-effects communicate by dispatching messages.

Building any app follows the same steps:

1. Define your data model with `init(flags)`
1. Define your data model with `init`
1. Define your messages with something like [`tagmeme`](https://github.com/andrejewski/tagmeme)
1. Define your behaviors with `update(message, state)`
1. Define your effects as functions which accept a dispatch function
Expand Down
28 changes: 13 additions & 15 deletions examples/make-n-model.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import React from 'react'
import react from 'raj/react'
import message from 'tagmeme'
import tag from 'tagmeme'

export function init () {
return {
makeId: null,
isLoading: false,
models: []
}
}
export const init = [{
makeId: null,
isLoading: false,
models: []
}]

export const SetMake = message()
export const ReceiveModels = message()
export const Msg = message.union([
export const SetMake = tag()
export const ReceiveModels = tag()
export const Msg = tag.union([
SetMake,
ReceiveModels
])
Expand All @@ -33,12 +31,12 @@ export function update (msg, state) {
])
}

export function loadModelsForMake (id, message) {
export function loadModelsForMake (id, tag) {
return function (dispatch) {
window.fetch(`/models?id=${id}`)
.then(res => res.json())
.then(res => {
dispatch(message(res.models))
dispatch(tag(res.models))
})
}
}
Expand All @@ -59,9 +57,9 @@ export function view (state, dispatch) {
}

export default function main () {
return react.program(React.Component, {
return react.program(React.Component, () => ({
init,
update,
view
})
}))
}
28 changes: 13 additions & 15 deletions examples/search.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import React from 'react'
import react from 'raj/react'
import message from 'tagmeme'
import tag from 'tagmeme'

export function init () {
return [{
searchQuery: '',
searchResults: [],
isLoading: false,
error: null
}]
}
export const init = [{
searchQuery: '',
searchResults: [],
isLoading: false,
error: null
}]

export const ChangeQuery = message()
export const ReceiveResults = message()
export const ReceiveError = message()
export const Search = message.union([
export const ChangeQuery = tag()
export const ReceiveResults = tag()
export const ReceiveError = tag()
export const Search = tag.union([
ChangeQuery,
ReceiveError,
ReceiveResults
Expand Down Expand Up @@ -80,9 +78,9 @@ export function fetchResults (query) {
}

export function main () {
return react.program(React.Component, {
return react.program(React.Component, () => ({
init,
update,
view
})
}))
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "raj",
"description": "The best JavaScript framework",
"version": "0.0.6",
"author": "Chris Andrejewski <christopher.andrejewski@gmail>",
"author": "Chris Andrejewski <christopher.andrejewski@gmail.com>",
"bugs": {
"url": "https://github.com/andrejewski/raj/issues"
},
Expand All @@ -20,8 +20,8 @@
"keywords": [
"best",
"framework",
"runtime",
"react"
"react",
"runtime"
],
"license": "MIT",
"main": "index.js",
Expand Down
8 changes: 5 additions & 3 deletions react.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const {program} = require('./runtime')

function reactProgram (Component, {init, update, view}) {
function reactProgram (Component, createApp) {
return class ReactProgram extends Component {
constructor (props) {
super(props)
let initial = true
const {init, update, view} = createApp(props)
this._view = view
program({
init: init(props),
init,
update,
view: (state, dispatch) => {
this._dispatch = dispatch
Expand All @@ -21,7 +23,7 @@ function reactProgram (Component, {init, update, view}) {
}

render () {
return view(this.state.state, this._dispatch)
return this._view(this.state.state, this._dispatch)
}
}
}
Expand Down
26 changes: 13 additions & 13 deletions test/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import {program} from '../react'
import {shallow} from 'enzyme'

test('program() should return a React component', t => {
const Program = program(React.Component, {
init: () => ['hello'],
const Program = program(React.Component, () => ({
init: ['hello'],
update: (msg, state) => [state],
view: state => React.createElement('p', null, state)
})
}))

const wrapper = shallow(React.createElement(Program, null))
const paragraph = wrapper.find('p')
Expand All @@ -17,14 +17,14 @@ test('program() should return a React component', t => {

test('program() should update the React component', t => {
let d
const Program = program(React.Component, {
init: () => ['hello'],
const Program = program(React.Component, () => ({
init: ['hello'],
update: (msg, state) => [msg],
view: (state, dispatch) => {
d = dispatch
return React.createElement('p', null, state)
}
})
}))

const wrapper = shallow(React.createElement(Program, null))
{
Expand All @@ -42,13 +42,13 @@ test('program() should update the React component', t => {

test('program() should init with component props', t => {
const props = {foo: 'bar'}
const Program = program(React.Component, {
init: p => {
t.deepEqual(p, props)
return ['hello']
},
update: (msg, state) => [state],
view: state => React.createElement('p', null, state)
const Program = program(React.Component, p => {
t.deepEqual(p, props)
return {
init: ['hello'],
update: (msg, state) => [state],
view: state => React.createElement('p', null, state)
}
})

shallow(React.createElement(Program, props))
Expand Down

0 comments on commit 57aa624

Please sign in to comment.