Created
April 18, 2018 23:53
-
-
Save dwhitney/b23cc393c7515780a30fb8b5156d94fd to your computer and use it in GitHub Desktop.
React stuff based on purescript-react-basic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Prelude | |
import Control.Monad.Eff (Eff) | |
import Unsafe.Coerce (unsafeCoerce) | |
h1 :: forall props. { | props } -> Array ReactElement -> ReactElement | |
h1 props children = element "h1" props children | |
text :: String -> ReactElement | |
text = unsafeCoerce | |
parent :: ReactComponent {} | |
parent = createReactComponent spec | |
where | |
spec = { displayName, initialState, update, render } | |
displayName = "Parent" | |
initialProps = {} | |
initialState = { count : 0 } | |
update = \_ s -> s | |
render = \props state setState -> children state setState | |
where | |
children state setState = fragment [(title state), statelessH1, (child1 state setState), (child2 state setState)] | |
title state = h1 {} [(text "Count: "), (text $ show state.count)] | |
statelessH1 = h1 {} [text "PureScript: This shouldn't update"] | |
child1 state setState = createReactElement child { count : state.count, handleClick : (handle setState) } | |
child2 state setState = createReactElement child { count : state.count, handleClick : (handle setState) } | |
handle setState = setState \state -> state { count = state.count + 1 } | |
child :: forall eff. ReactComponent { count :: Int, handleClick :: Eff eff Unit } | |
child = createReactComponent spec | |
where | |
spec = { displayName, update, render, initialState } | |
displayName = "Child" | |
initialState = {} | |
update = \_ s -> s | |
render = \props _ _ -> h1 { onClick : props.handleClick } [(text "Increment : ") , (text $ show props.count)] | |
main :: Eff () Unit | |
main = renderDOM $ createReactElement parent {} | |
type Spec props state eff = | |
{ displayName :: String | |
, initialState :: { | state } | |
, update :: { | props } -> { | state } -> { | state } | |
, render :: { | props } -> { | state } -> SetState state eff -> ReactElement | |
} | |
type SetState state eff = ({ | state } -> { | state }) -> Eff eff Unit | |
foreign import data ReactComponent :: Type -> Type | |
foreign import data ReactElement :: Type | |
foreign import element :: forall props. String -> { | props } -> Array ReactElement -> ReactElement | |
foreign import createReactElement :: forall props. ReactComponent { | props } -> { | props } -> ReactElement | |
foreign import createReactComponent :: forall props state eff. Spec props state eff -> ReactComponent { | props} | |
foreign import fragment :: Array ReactElement -> ReactElement | |
foreign import renderDOM :: forall eff. ReactElement -> Eff eff Unit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const React = require("react"); | |
const ReactDOM = require("react-dom"); | |
const Test = require("../../build/test.js"); | |
exports.createReactElement = function(component){ | |
return function(props){ | |
return Test.createReactElement(component)(props)(null); | |
}; | |
}; | |
exports.createReactComponent = function(spec){ | |
return Test.createReactComponent(spec.displayName)(spec.initialState)(spec.render); | |
}; | |
exports.element = Test.createReactElement | |
exports.fragment = Test.fragment; | |
exports.renderDOM = function(reactElement){ | |
return function(){ | |
ReactDOM.render(reactElement, document.getElementById("root")); | |
}; | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
const { Component, Fragment } = React; | |
import createReactClass from 'create-react-class'; | |
export const createReactComponent = displayName => initialState => renderFn => { | |
class Comp extends Component{ | |
constructor(props){ | |
super(props); | |
this.state = initialState; | |
} | |
render(){ | |
return renderFn(this.props)(this.state)(newState => () => this.setState(newState)); | |
} | |
}; | |
Comp.displayName = displayName; | |
console.log(Comp); | |
return Comp; | |
} | |
export const createReactElement = nameOrComponent => initialProps => children => { | |
return React.createElement.apply(React, [nameOrComponent, initialProps].concat(children)); | |
}; | |
export const fragment = children => { | |
return React.createElement.apply(React, [Fragment, {}].concat(children)); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment