Update externally
Intro
Ripples are made to be used inside a React application. However, you can also update the ripples externally.
The purpose of Ripple
is to not make any compromise between the pattern you want to apply to your application.
Example:
- Lake.ts
- Service.ts
- MyComponent.tsx
/*
This define the Lake where the ripples will belong to.
*/
import { createRipples } from "@m-c2/ripple";
const lake = createRipples({
counter : { count: 0}
});
// We export the hooks for component usage only
export const rippleHooks = lake[0];
// We export the services for external usage
export const rippleServices = lake[1];
/*
This define the services that will be used
to update the ripples outside the React lifecycle.
*/
import { rippleServices } from "./Lake";
const { updateCounter } = services;
/**
* @class CounterService
* @description A simple counter service
*/
class CounterService {
get counter() {
return updateCounter();
}
/**
* Increment the counter
* @returns {void}
*/
increment() {
this.counter(_ => { _.count++ });
}
/**
* Decrement the counter
* @returns {void}
*/
reset() {
this.counter(_ => "reset" );
}
}
export const counterService = new CounterService();
/*
This is a simple component that will use the counter service
to update the counter value.
*/
import React, { CSSProperties } from 'react';
import { rippleHooks } from "./Lake";
import { counterService } from "./Service";
const {useCounter} = rippleHooks;
const styles = {
div: {
border : "1px solid white",
width : "110px",
padding : 10,
},
button: {
width: "100%",
},
p: {
textAlign : "center",
borderBottom : "1px solid white",
},
} as { [key: string]: CSSProperties }
/**
* Here we do not pass the count value to the component
* because it is already available in the ripple.
*/
const MyComponent = ({ increment, reset }) => {
const [{count}] = useCounter();
return (
<div style={styles.div}>
<p style={styles.p}>Counter: {count}</p>
<button
style={styles.button}
onClick={() => counterService.increment()}
>Increment</button>
<button
style={styles.button}
onClick={() => counterService.reset()}
>Reset</button>
</div>
);
};
export default MyComponent;
See it in action
Counter: 0
The updater
Let's study the updater service:
- Service.ts
// we import the services
import { rippleServices } from "./Lake";
// we destructure the services to extract the counter updater
const { updateCounter } = rippleServices;
Function | Parameter type | value | Description | Trigger a render |
---|---|---|---|---|
updateCounter | void | undefined | Return the counter value | no |
updateCounter | function | handler: (ripple) => void | "restore" | "reset" | typeof ripple | do an action to the ripple | yes / No |
- usage
// updateCounter(void) => ripple
const ripple = updateCounter();
// updateCounter(handler: (ripple) => void | "restore" | "reset" | typeof ripple) => void
updateCounter(ripple => { ... });
Updater handler
Function | return type | return value | Description | Trigger a render |
---|---|---|---|---|
handler | void | undefined | apply all pending modification to the ripple | yes |
handler | string | restore | cancel pending modifications | no |
handler | string | reset | reset the ripple to its initial state | no |
handler | typeof ripple | a new ripple | replace the ripple with a new value. Does not replace the initial state | yes |
- usage
// apply all pending modification to the ripple
// updateCounter(handler: (ripple) => void ) => void
updateCounter(ripple => {
ripple.count++;
});
// cancel pending modifications
// updateCounter(handler: (ripple) => "restore") => void
updateCounter(ripple => "restore");
// reset the ripple to its initial state
// updateCounter(handler: (ripple) => "reset") => void
updateCounter(ripple => "reset");
// replace the ripple with a new value. Does not replace the initial state
// updateCounter(handler: (ripple) => typeof ripple) => void
updateCounter(ripple => {
return {
count: 0,
};
});