Skip to content

Instantly share code, notes, and snippets.

@broerjuang
Created February 9, 2018 18:39
Show Gist options
  • Save broerjuang/cb917c68966ad848878c73666310bb70 to your computer and use it in GitHub Desktop.
Save broerjuang/cb917c68966ad848878c73666310bb70 to your computer and use it in GitHub Desktop.
This is the implementation of thinking in react using reason
type product = {
category: string,
price: string,
stocked: bool,
name: string
};
type products = list(product);
let products = [
{category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
{category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
{category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
{category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
{category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
{category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];
module ProductCategoryRow = {
let component = ReasonReact.statelessComponent("ProductCategoryRow");
let make = (~category, _children) => {
...component,
render: (_self) => <tr> <th colSpan=2> (ReasonReact.stringToElement(category)) </th> </tr>
};
};
module ProductRow = {
let component = ReasonReact.statelessComponent("ProductRow");
let make = (~product, _children) => {
...component,
render: (_self) =>
<tr>
<td> (ReasonReact.stringToElement(product.name)) </td>
<td> (ReasonReact.stringToElement(product.price)) </td>
</tr>
};
};
module ProductTable = {
let component = ReasonReact.statelessComponent("ProductTable");
let make = (~showProductInStock, ~filteredText=?, ~products, _children) => {
...component,
render: (_self) => {
let textValue =
switch filteredText {
| Some(value) => value
| None => ""
};
let productList =
products
|> List.filter(
(product) =>
Js.String.includes(textValue |> String.lowercase, product.name |> String.lowercase)
&& showProductInStock === product.stocked
)
|> List.mapi((id, product) => <ProductRow product key=(string_of_int(id)) />);
<table>
<thead>
<tr>
<th> (ReasonReact.stringToElement("Name")) </th>
<th> (ReasonReact.stringToElement("Price")) </th>
</tr>
</thead>
<tbody> (productList |> Array.of_list |> ReasonReact.arrayToElement) </tbody>
</table>
}
};
};
module Searchbar = {
let component = ReasonReact.statelessComponent("Searchbar ");
let make = (~onHandleInputChange, ~inStockOnly, ~onChange, _children) => {
...component,
render: (_self) =>
<form>
<input onChange _type="text" placeholder="search" />
<p>
<input
_type="checkbox"
checked=(inStockOnly ? Js.true_ : Js.false_)
onChange=onHandleInputChange
/>
(ReasonReact.stringToElement(" only show product in stock"))
</p>
</form>
};
};
type state = {
filteredText: option(string),
showProductInStock: bool
};
type action =
| OnSearch(string)
| OnShowProductInStock;
let component = ReasonReact.reducerComponent("FilterableProductTable");
let make = (_children) => {
...component,
initialState: () => {filteredText: None, showProductInStock: false},
reducer: (action, state) =>
switch action {
| OnSearch(text) => ReasonReact.Update({...state, filteredText: Some(text)})
| OnShowProductInStock =>
ReasonReact.Update({...state, showProductInStock: ! state.showProductInStock})
},
render: (self) => {
let onSearchText = (e) =>
ReactEventRe.Form.target(e)
|> ReactDOMRe.domElementToObj
|> ((result) => result##value |> ((value) => self.send(OnSearch(value))));
let onHandleInputChange = (_e) => self.send(OnShowProductInStock);
<div>
<Searchbar
onChange=onSearchText
inStockOnly=self.state.showProductInStock
onHandleInputChange
/>
<ProductTable
products
filteredText=?self.state.filteredText
showProductInStock=self.state.showProductInStock
/>
</div>
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment