Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
react-aptor
Advanced tools
Minimal API Connector for react
English | Persian | (add your language)
Don’t waste your time by finding react version of your favorite javascript package, keep control of your API
now.
Documentation: You can find the react-aptor documentation on the website.
Most packages are developed separately in JavaScript for increasing generality being library/framework agnostic.
Connecting vanilla third parties to react is not a routine task especially for those that need to change the DOM.
On the other hand, these packages might be developed by different teams, hence development progress can be one step behind the original or even be terminated at any time. Also, wrong abstraction or bad design patterns may interrupt the progress of these react-xyz
packages.
If you are still not convinced you can read this article
Other Concerns:
We strive to solve all mentioned problems at once and for all.
Connect your react app to any third party in three-step
useAptor
import Something from 'some-third-party';
export default function instantiate(node, params) {
return new Something(node, params);
}
This function will return an instance of the third-party package. You have access to node (DOM-node*) and params.
The
node
is passed by react-aptor as a reference to DOM that is occasionally used as a wrapper for embedding UI. The DOM-node* will become more clear in the third step.The
params
are optional parameters that are passed by react-aptor and defined by you. see the third step. The params will be passed by you and will be more clear in the third step.name this file construct.js as convention ✨.
export default function getAPI(instance, params) {
// return corresponding API Object
return () => ({
api_key: () => {
/* api definition using instance and params */
console.log(instance);
},
});
}
The react-aptor will pass the latest instance of your third party which has been defined in the first step by the instantiate function along with params to getAPI function.
The
instance
is returned instance of your third party. Technically it is exactly going to be instantiate(node, params)The
params
are optional parameters that are passed by react-aptor and defined by you. see the third step. The params will be passed by you and will be more clear in the third step.name this file api.js as convention ✨.
useAptor
import useAptor from 'react-aptor';
import getAPI from './api';
import instantiate from './construct';
const Connector = (props, ref) => {
const aptorRef = useAptor(ref, {
getAPI,
instantiate,
/* params: anything */
});
return <div ref={aptorRef} />;
};
export default React.forwardRef(Connector);
name this file connector.jsx as convention ✨ If you are using react 17 or newer version, you can also name it connector.js
useAptor in one look
const aptorRef = useAptor(ref, configuration, deps);
ref
For the connection phase, you need to define a forwardRef component. The useAptor
hook needs forwarded-ref as the first argument, this is necessary to bind all your defined API to this ref.
configuration
As the configuration argument you need to pass defined instantiate (defined in the first step ☝️), getAPI (defined in the second step ☝️) and your custom params argument. The useAptor hook will return you a ref (aptorRef
) which you can bind to your DOM node.
The
params
doesn't have any limitation, it can be any arbitrary type e.g. undefined, number, string, or an object containing all of them. The params will be then passed to your instantiate and getAPI function, as you saw in the first and second steps. Params is the best place to connect props to your low-level API it means ”No Need” for extra function generation 🥳
deps
Is the same as Dependencies array default value is []
but you can override it as the third and last argument of useAptor. It may be needed in a situation in which you want to force re-instantiate by some prop change. It will use shallow comparison (as react do) for dependency array and will call your instantiate
& getAPI
in a row.
const Main = () => {
const ref = createRef();
const apiKeyHandler = () => {
if (ref.current) {
ref.current.api_key();
}
};
return (
<div>
<Connector ref={ref} />
<Button onClick={apiKeyHandler}>api call</Button>
</div>
);
};
Pass createRef to the Connector component (made in the third step), and then you can access all of the APIs inside ref.current
function call can be much more readable with optional chaining & related babel plugin
const apiKeyHandler = () => ref.current?.api_key();
In case you need
ref.current
more than one time, it is a good idea to rename it in the first place
const apiKeyHandler = () => {
const { current: api } = ref; // store ref.current in `api`
if (api) {
api.api_key();
}
};
Cause the default value for ref can be undefined (in createRef) and null (in useRef) Typescript will complain about possibility for not-existence of apis. see more. In a normal world react will bind your API to the given ref after the Connector mount
If you're using ref in useEffect or somewhere which is guaranteed to have the ref bounded to values, you can return a proxy object in your getAPI
function to bind all api functions simultaneously.
export default function getAPI(thirdParty, params) {
if (!thirdParty)
return () =>
new Proxy(
{},
{
get: (_, prop) => {
// Possible to mock differently for different props
return noop;
},
}
);
return () => ({
api_key() {
// third-party is defined here for sure :)
console.log(thirdParty);
},
});
}
You can access all of your APIs via
this
keyword
export default function getAPI(sound, params) {
return () => ({
_state() {
return sound.getState();
},
play() {
if (this._state() === 'LOADED') sound.play();
},
});
}
It's better to start the name of these internal functions with
_
this
problem in API objectIn a case, you see this keyword usage in third-party API
you must specify this
something other than returned API object.
The following examples are for howler integration using react-aptor:
{
// ❌ It doesn't work
state: howler.state,
// 🆗 this is Okay
state: howler.state.bind(howler),
// 🆗 this is also Okay
state: () => howler.state(),
// 🆗 this is also Okay, too
state() {
return howler.state();
}
}
You can use something like the follwing:
export type APITypes = ReturnType<ReturnType<typeof getAPI>>;
useEffect
and proper deps
arrayFor another possible usage see our production ready examples:
required
The react useRef or createRef ref instance which has been passed throw react.forwardRef method. your API will be stored in this ref.
required
required
function(node, params): Instance
A function that receives probable bounded-node and params. It then returns an instance of your third party.
function(previousInstance, params): void
A function that receives previously created instances and params. It is useful when you want to perform the cleanup before new instance creation. e.g. remove event listeners, free up allocated memories, destroy internally & etc
required
function(Instance, params): ApiObject
A function that receives instances of your third-party and params. It then returns a key-value pair object for API handlers.
any
Params can have any arbitrary type and can be used with props or pre-defined options.
[]
React dependencies array for re-instantiating your third-party packages. It will call instantiate
with the latest node, params whenever shallow comparison for with the previous deps array finds inequality.
💻 Developer/Maintainer (BTC):
bc1qq8qq63ex7svkkjdjn5axu8angfxytvs83nlujk
🎨 Designer (BTC):
bc1q9fahyct3lrdz47pjf4kfxvsyum2dm74v2hv9xl
NOTE: Add your favorite package to the following list by creating a new issue.
FAQs
React API connector
The npm package react-aptor receives a total of 10,416 weekly downloads. As such, react-aptor popularity was classified as popular.
We found that react-aptor demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.