Comparing version 0.0.20 to 0.0.21
@@ -21,5 +21,6 @@ export declare type ForgoRef<T> = { | ||
export declare type ForgoComponent<TProps extends ForgoElementProps> = { | ||
render: (props: TProps, args: ForgoRenderArgs) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
error?: (props: TProps, args: ForgoErrorArgs) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
render: (props: TProps, args: ForgoRenderArgs) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
unmount?: () => void; | ||
shouldUpdate?: (newProps: TProps, oldProps: TProps) => boolean; | ||
}; | ||
@@ -26,0 +27,0 @@ export declare type ForgoElement<TType extends string | ForgoComponentCtor<TProps>, TProps extends ForgoElementProps> = { |
@@ -149,13 +149,21 @@ "use strict"; | ||
if (fullRerender || | ||
havePropsChanged(savedComponentState.props, forgoElement.props)) { | ||
// Since we have compatible state already stored, | ||
// we'll push the savedComponentState into pending states for later attachment. | ||
const statesToAttach = pendingAttachStates.concat(Object.assign(Object.assign({}, savedComponentState), { props: forgoElement.props })); | ||
// Get a new element by calling render on existing component. | ||
const newForgoElement = savedComponentState.component.render(forgoElement.props, savedComponentState.args); | ||
return boundaryFallback(node, forgoElement.props, savedComponentState.args, statesToAttach, fullRerender, boundary, () => { | ||
// Pass it on for rendering... | ||
return internalRender(newForgoElement, node, statesToAttach, fullRerender, boundary); | ||
}); | ||
havePropsChanged(forgoElement.props, savedComponentState.props)) { | ||
if (!savedComponentState.component.shouldUpdate || | ||
savedComponentState.component.shouldUpdate(forgoElement.props, savedComponentState.props)) { | ||
// Since we have compatible state already stored, | ||
// we'll push the savedComponentState into pending states for later attachment. | ||
const statesToAttach = pendingAttachStates.concat(Object.assign(Object.assign({}, savedComponentState), { props: forgoElement.props })); | ||
// Get a new element by calling render on existing component. | ||
const newForgoElement = savedComponentState.component.render(forgoElement.props, savedComponentState.args); | ||
return boundaryFallback(node, forgoElement.props, savedComponentState.args, statesToAttach, fullRerender, boundary, () => { | ||
// Pass it on for rendering... | ||
return internalRender(newForgoElement, node, statesToAttach, fullRerender, boundary); | ||
}); | ||
} | ||
// shouldUpdate() returned false | ||
else { | ||
return { node, boundary }; | ||
} | ||
} | ||
// not a fullRender and havePropsChanged() returned false | ||
else { | ||
@@ -431,3 +439,3 @@ return { node, boundary }; | ||
*/ | ||
function havePropsChanged(oldProps, newProps) { | ||
function havePropsChanged(newProps, oldProps) { | ||
const oldKeys = Object.keys(oldProps); | ||
@@ -474,7 +482,10 @@ const newKeys = Object.keys(newProps); | ||
const effectiveProps = typeof props !== "undefined" ? props : component.props; | ||
const forgoNode = component.component.render(effectiveProps, component.args); | ||
const statesToAttach = state.components | ||
.slice(0, element.componentIndex) | ||
.concat(Object.assign(Object.assign({}, component), { props: effectiveProps })); | ||
internalRender(forgoNode, element.node, statesToAttach, fullRerender); | ||
if (!component.component.shouldUpdate || | ||
component.component.shouldUpdate(effectiveProps, component.props)) { | ||
const forgoNode = component.component.render(effectiveProps, component.args); | ||
const statesToAttach = state.components | ||
.slice(0, element.componentIndex) | ||
.concat(Object.assign(Object.assign({}, component), { props: effectiveProps })); | ||
internalRender(forgoNode, element.node, statesToAttach, fullRerender); | ||
} | ||
} | ||
@@ -481,0 +492,0 @@ else { |
{ | ||
"name": "forgo", | ||
"version": "0.0.20", | ||
"version": "0.0.21", | ||
"main": "./dist", | ||
@@ -5,0 +5,0 @@ "devDependencies": { |
@@ -132,2 +132,19 @@ # forgo | ||
## Bailing out of a render | ||
When the shouldUpdate() function is defined for a component, Forgo will call it with newProps and oldProps and check if the return value is true before rendering the component. Returning false will skip rendering the component. | ||
```jsx | ||
function Greeter(props) { | ||
return { | ||
render(props, args) { | ||
return <div>Hello {props.firstName}</div>; | ||
}, | ||
shouldUpdate(newProps, oldProps) { | ||
return newProps.firstName !== oldProps.firstName; | ||
}, | ||
}; | ||
} | ||
``` | ||
## Error handling | ||
@@ -134,0 +151,0 @@ |
114
src/index.ts
@@ -44,2 +44,6 @@ /* | ||
export type ForgoComponent<TProps extends ForgoElementProps> = { | ||
render: ( | ||
props: TProps, | ||
args: ForgoRenderArgs | ||
) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
error?: ( | ||
@@ -49,7 +53,4 @@ props: TProps, | ||
) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
render: ( | ||
props: TProps, | ||
args: ForgoRenderArgs | ||
) => ForgoElement<ForgoComponentCtor<TProps>, TProps>; | ||
unmount?: () => void; | ||
shouldUpdate?: (newProps: TProps, oldProps: TProps) => boolean; | ||
}; | ||
@@ -340,36 +341,50 @@ | ||
fullRerender || | ||
havePropsChanged(savedComponentState.props, forgoElement.props) | ||
havePropsChanged(forgoElement.props, savedComponentState.props) | ||
) { | ||
// Since we have compatible state already stored, | ||
// we'll push the savedComponentState into pending states for later attachment. | ||
const statesToAttach = pendingAttachStates.concat({ | ||
...savedComponentState, | ||
props: forgoElement.props, | ||
}); | ||
if ( | ||
!savedComponentState.component.shouldUpdate || | ||
savedComponentState.component.shouldUpdate( | ||
forgoElement.props, | ||
savedComponentState.props | ||
) | ||
) { | ||
// Since we have compatible state already stored, | ||
// we'll push the savedComponentState into pending states for later attachment. | ||
const statesToAttach = pendingAttachStates.concat({ | ||
...savedComponentState, | ||
props: forgoElement.props, | ||
}); | ||
// Get a new element by calling render on existing component. | ||
const newForgoElement = savedComponentState.component.render( | ||
forgoElement.props, | ||
savedComponentState.args | ||
); | ||
// Get a new element by calling render on existing component. | ||
const newForgoElement = savedComponentState.component.render( | ||
forgoElement.props, | ||
savedComponentState.args | ||
); | ||
return boundaryFallback( | ||
node, | ||
forgoElement.props, | ||
savedComponentState.args, | ||
statesToAttach, | ||
fullRerender, | ||
boundary, | ||
() => { | ||
// Pass it on for rendering... | ||
return internalRender( | ||
newForgoElement, | ||
node, | ||
statesToAttach, | ||
fullRerender, | ||
boundary | ||
); | ||
} | ||
); | ||
} else { | ||
return boundaryFallback( | ||
node, | ||
forgoElement.props, | ||
savedComponentState.args, | ||
statesToAttach, | ||
fullRerender, | ||
boundary, | ||
() => { | ||
// Pass it on for rendering... | ||
return internalRender( | ||
newForgoElement, | ||
node, | ||
statesToAttach, | ||
fullRerender, | ||
boundary | ||
); | ||
} | ||
); | ||
} | ||
// shouldUpdate() returned false | ||
else { | ||
return { node, boundary }; | ||
} | ||
} | ||
// not a fullRender and havePropsChanged() returned false | ||
else { | ||
return { node, boundary }; | ||
@@ -754,3 +769,3 @@ } | ||
*/ | ||
function havePropsChanged(oldProps: any, newProps: any) { | ||
function havePropsChanged(newProps: any, oldProps: any) { | ||
const oldKeys = Object.keys(oldProps); | ||
@@ -806,15 +821,20 @@ const newKeys = Object.keys(newProps); | ||
const forgoNode = component.component.render( | ||
effectiveProps, | ||
component.args | ||
); | ||
if ( | ||
!component.component.shouldUpdate || | ||
component.component.shouldUpdate(effectiveProps, component.props) | ||
) { | ||
const forgoNode = component.component.render( | ||
effectiveProps, | ||
component.args | ||
); | ||
const statesToAttach = state.components | ||
.slice(0, element.componentIndex) | ||
.concat({ | ||
...component, | ||
props: effectiveProps, | ||
}); | ||
const statesToAttach = state.components | ||
.slice(0, element.componentIndex) | ||
.concat({ | ||
...component, | ||
props: effectiveProps, | ||
}); | ||
internalRender(forgoNode, element.node, statesToAttach, fullRerender); | ||
internalRender(forgoNode, element.node, statesToAttach, fullRerender); | ||
} | ||
} else { | ||
@@ -821,0 +841,0 @@ throw new Error(`Missing forgo state on node.`); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
81627
1405
381