Skip to content

Commit

Permalink
emmm
Browse files Browse the repository at this point in the history
  • Loading branch information
yisar committed Oct 18, 2023
1 parent a9faf74 commit b0de603
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 32 deletions.
222 changes: 207 additions & 15 deletions demo/app.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,208 @@
import { h, render, useState, Fragment, useEffect } from './fre'


const App = () => {
useEffect(()=>{
console.log(123)
},[])
const [count, setCount] = useState(0)
console.log(count)
return <>
<button onClick={() => setCount(count + 1)}>
{count}
</button>
</>
import { h, render, useReducer, useCallback } from "../src/index"

function random(max) {
return Math.round(Math.random() * 1000) % max
}

const A = [
"pretty",
"large",
"big",
"small",
"tall",
"short",
"long",
"handsome",
"plain",
"quaint",
"clean",
"elegant",
"easy",
"angry",
"crazy",
"helpful",
"mushy",
"odd",
"unsightly",
"adorable",
"important",
"inexpensive",
"cheap",
"expensive",
"fancy",
]
const C = [
"red",
"yellow",
"blue",
"green",
"pink",
"brown",
"purple",
"brown",
"white",
"black",
"orange",
]
const N = [
"table",
"chair",
"house",
"bbq",
"desk",
"car",
"pony",
"cookie",
"sandwich",
"burger",
"pizza",
"mouse",
"keyboard",
]

let nextId = 1

function buildData(count) {
const data = new Array(count)
for (let i = 0; i < count; i++) {
data[i] = {
id: nextId++,
label: `${A[random(A.length)]} ${C[random(C.length)]} ${N[random(N.length)]
}`,
}
}
return data
}

function listReducer(state, action) {
const { data, selected } = state
switch (action.type) {
case "RUN":
return { data: buildData(1000), selected: 0 }
case "RUN_LOTS":
return { data: buildData(10000), selected: 0 }
case "ADD":
return { data: data.concat(buildData(1000)), selected }
case "UPDATE":
const newData = data.slice(0)
for (let i = 0; i < newData.length; i += 10) {
const r = newData[i]
newData[i] = { id: r.id, label: r.label + " !!!" }
}
return { data: newData, selected }
case "CLEAR":
return { data: [], selected: 0 }
case "SWAP_ROWS":
return data.length > 998 ? { data: [data[0], data[998], ...data.slice(2, 998), data[1], data[999]], selected } : state
case "REMOVE":
const idx = data.findIndex((d) => d.id === action.id)
return { data: [...data.slice(0, idx), ...data.slice(idx + 1)], selected }
case "SELECT":
return { data, selected: action.id }
}
return state
}

const Row = ({ selected, item, dispatch, id }) => {
return (
<tr className={selected ? "danger" : ""}>
<td className="col-md-1">{item.id}</td>
<td className="col-md-4">
<a onClick={() => dispatch({ type: 'SELECT', id: item.id })
}>{item.label}</a>
</td>
<td className="col-md-1">
<a onClick={() => dispatch({ type: 'REMOVE', id: item.id })}>
<span className="glyphicon glyphicon-remove" aria-hidden="true" />
</a>
</td>
<td className="col-md-6" />
</tr>
)
}

const Button = ({ id, cb, title }) => (
<div className="col-sm-6 smallpad">
<button
type="button"
className="btn btn-primary btn-block"
id={id}
onClick={cb}
>
{title}
</button>
</div>
)


const Jumbotron = ({ dispatch }) => (
<div className="jumbotron">
<div className="row">
<div className="col-md-6">
<h1>Fre Hooks keyed</h1>
</div>
<div className="col-md-6">
<div className="row">
<Button
id="run"
title="Create 1,000 rows"
cb={() => dispatch({ type: "RUN" })}
/>
<Button
id="runlots"
title="Create 10,000 rows"
cb={() => dispatch({ type: "RUN_LOTS" })}
/>
<Button
id="add"
title="Append 1,000 rows"
cb={() => dispatch({ type: "ADD" })}
/>
<Button
id="update"
title="Update every 10th row"
cb={() => dispatch({ type: "UPDATE" })}
/>
<Button
id="clear"
title="Clear"
cb={() => dispatch({ type: "CLEAR" })}
/>
<Button
id="swaprows"
title="Swap Rows"
cb={() => dispatch({ type: "SWAP_ROWS" })}
/>
</div>
</div>
</div>
</div>
)

const Main = () => {
const [state, setState] = useReducer(listReducer, { data: [], selected: 0 })
const dispatch = useCallback(setState, [])

return (
<div className="container">
<Jumbotron dispatch={dispatch} />
<table className="table table-hover table-striped test-data">
<tbody>
{state.data.map((item) => {
return (
<Row
key={item.id + ''}
item={item}
selected={state.selected === item.id}
dispatch={dispatch}
/>
)
})}
</tbody>
</table>
<span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span>
</div>
)
}
render(<App />, document.body)

render(<Main />, document.body)
2 changes: 1 addition & 1 deletion demo/index.html → index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<title>Document</title>
</head>
<body>
<script src="./app.jsx" type="module"></script>
<script src="./demo/app.jsx" type="module"></script>
</body>
</html>
30 changes: 14 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function mount(vnode, isSvg) {
setDOMAttribute(node, key, props[key], isSvg)
}
}

let childrenRef = props.children == null ? null : mount(props.children, isSvg)
childrenRef && insertDom(node, childrenRef)
return {
Expand Down Expand Up @@ -196,9 +196,11 @@ function reconcile(
ref,
isSvg
) {
if (oldVnode === newVnode && !newVnode.dirty) {
return ref
} else if (isEmpty(newVnode) && isEmpty(oldVnode)) {
// if (oldVnode === newVnode) {
// return ref
// } else

if (isEmpty(newVnode) && isEmpty(oldVnode)) {
return ref
} else if (isLeaf(newVnode) && isLeaf(oldVnode)) {
ref.node.nodeValue = newVnode
Expand All @@ -208,10 +210,12 @@ function reconcile(
isElement(oldVnode) &&
newVnode.type === oldVnode.type
) {

isSvg = isSvg || newVnode.type === 'svg'
reconcileProps(ref.node, newVnode.props, oldVnode.props, isSvg)
let oldCh = oldVnode.props.children
let newCh = newVnode.props.children

if (oldCh == null) {
if (newCh != null) {
ref.children = mount(newCh, isSvg)
Expand All @@ -232,19 +236,15 @@ function reconcile(
}
}
return ref
} else if (isNonEmptyArray(newVnode) && isNonEmptyArray(oldVnode)) {
reconcileChildren(parent, newVnode, oldVnode, ref, isSvg)
return ref
} else if (
isComponent(newVnode) &&
isComponent(oldVnode) &&
newVnode.type === oldVnode.type
) {

let fn = newVnode.type
let shouldUpdate = newVnode.dirty || (fn.shouldUpdate != null
let shouldUpdate = fn.shouldUpdate != null
? fn.shouldUpdate(oldVnode.props, newVnode.props)
: defaultShouldUpdate(oldVnode.props, newVnode.props))
: defaultShouldUpdate(oldVnode.props, newVnode.props)

if (shouldUpdate) {
currentVnode = newVnode
Expand Down Expand Up @@ -274,11 +274,9 @@ function reconcile(
} else {
return ref
}
} else if (newVnode instanceof Node && oldVnode instanceof Node) {
ref.node = newVnode
return ref
} else {
return mount(newVnode, isSvg)
reconcileChildren(parent, newVnode, oldVnode, ref, isSvg)
return ref
}
}

Expand Down Expand Up @@ -435,8 +433,8 @@ const useReducer = (
: value
if (hook[0] !== v) {
hook[0] = v
c.dirty = true
defer(() => render(c, rootRef))
c.type.shouldUpdate = () => true
render(c, rootRef)
}
}
}
Expand Down
File renamed without changes.

0 comments on commit b0de603

Please sign in to comment.