Skip to content

Commit

Permalink
Adds in createSideEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
tbranyen committed Mar 29, 2022
1 parent 1eea808 commit 8ad6692
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/diffhtml-components/lib/create-side-effect.js
Expand Up @@ -30,7 +30,7 @@ export function createSideEffect(sideEffectFn = EMPTY.FUN) {
// Always unmount first
unMount();

unMount = sideEffectFn();
unMount = sideEffectFn() || EMPTY.FUN;

if (typeof unMount === 'function') {
activeComponent.componentWillUnmount = () => unMount();
Expand Down
15 changes: 13 additions & 2 deletions packages/diffhtml-components/lib/middleware.js
@@ -1,4 +1,4 @@
import { ComponentTreeCache, VTree, Transaction } from './util/types';
import { EMPTY, ComponentTreeCache, VTree, Transaction } from './util/types';
import globalThis from './util/global';
import onceEnded from './once-ended';
import componentWillUnmount from './lifecycle/component-will-unmount';
Expand Down Expand Up @@ -100,9 +100,20 @@ const syncTreeHook = (oldTree, newTree) => {
// Loop through childNodes seeking out components to render.
for (let i = 0; i < newTree.childNodes.length; i++) {
const newChildTree = newTree.childNodes[i];
const oldChildTree = (oldTree.childNodes && oldTree.childNodes[i]) || EMPTY.OBJ;

const isOldFunction = Boolean(ComponentTreeCache.get(oldChildTree));
const isNewFunction = typeof newChildTree.rawNodeName === 'function';

// Previous slot was a component and the new slot is not, therefore we
// should be indicating this component is unmounting.
if (isOldFunction && !isNewFunction) {
releaseHook(oldChildTree);
}

// If the old slot was not a component, and the new tree is, then we are
// rendering a brand new component.
if (typeof newChildTree.rawNodeName === 'function') {
const oldChildTree = oldTree.childNodes && oldTree.childNodes[i];
const renderTree = render(oldChildTree, newChildTree);

// If nothing was rendered, return the oldTree.
Expand Down
5 changes: 5 additions & 0 deletions packages/diffhtml-components/lib/once-ended.js
Expand Up @@ -7,6 +7,10 @@ const { NodeCache, PATCH_TYPE, decodeEntities } = diff.Internals;
const uppercaseEx = /[A-Z]/g;

/**
* Once the transaction has ended we can know for certain that DOM operations
* have completed and can trigger lifecycle methods like componentDidMount or
* componentWillUnmount.
*
* @param {Transaction} transaction
*/
export default transaction => {
Expand All @@ -22,6 +26,7 @@ export default transaction => {
while (true) {
const patchType = patches[i];

// Exhausted remaining patches.
if (i === length) {
break;
}
Expand Down
13 changes: 11 additions & 2 deletions packages/diffhtml-website/pages/components.md
Expand Up @@ -211,6 +211,8 @@ The function `createState` is used to make a stateful component out of a
function component. It mimics the API of `useState` from React. Essentially you
must execute this function in the same spot at the same time every render.

This API is similar to `useState` from React.

<a name="create-state-examples"></a>

### <a href="#create-state-examples"><u>Examples</u></a>
Expand Down Expand Up @@ -241,7 +243,10 @@ innerHTML(main, html`<${Example} />`);
## <a href="#create-side-effect">createSideEffect</a>

The function `createSideEffect` is used to schedule some work after a component
has updated.
has mounted, unmounted, or updated. This works similar to the `useEffect` hook
found in React.

This API is similar to `useEffect` from React.

<a name="create-side-effect-examples"></a>

Expand All @@ -253,7 +258,11 @@ import { createSideEffect } from 'diffhtml-components';

function Example() {
createSideEffect(() => {
console.log('Component has rendered');
console.log('Component has mounted or updated');

return () => {
console.log('Component has unmounted');
};
});

return html`
Expand Down

0 comments on commit 8ad6692

Please sign in to comment.