Skip to content

Instantly share code, notes, and snippets.

@dwhitney
Created April 18, 2018 23:53
Show Gist options
  • Save dwhitney/b23cc393c7515780a30fb8b5156d94fd to your computer and use it in GitHub Desktop.
Save dwhitney/b23cc393c7515780a30fb8b5156d94fd to your computer and use it in GitHub Desktop.
React stuff based on purescript-react-basic
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
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"));
};
};
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