Wrap mutant. React. Rendered Array (beta)
Object mutation is easy and extremelly fast. But such libraries like react make us to rebuild objects on every their change. It's not a problem on simple and small objects. When your object is a big array, your application become slow. When you are trying to handle complicated deeply nested object, it becomes a brain cancer.
Solution is in wrapping that big or complex objects into Proxy object.
Examples
pravosleva's substring-highlight-sample [demo | repo]
This package is addition of @wrap-mutant/react integration. To understand how actually it works please read the docs of @wrap-mutant/core and @wrap-mutant/react.
This package is separated from @wrap-mutant/react because of different release cycles and build targets.
About
This package allows you avoid re-render of huge array of components and that's how you win the performance. It will be useful when you have to render large number of components without pagination, for example, in endless scroll (hello, LinkedIn, you are really slow) or when you render SVG.
What do you win? When we render containers, we have 2 loops:
- Array rebuilding
- Array mapping into
JSX.Element
So, if @wrap-mutant/react's useWMState
makes you avoid the first one, this package is aimed to avoid the second. It means this package allows you to render Array
s always by O(1)
. This is how you win the performance.
I know API makes you think "not exactly what I want..." and you are right. But as engeneers we have to pay something to win something else. You have to implement small adapter component which prepare props for your target component.
Because of provided by this package Array
s are already wrapped, it would be good to pass { wrap: false }
into useWMState
's options.
Your skill requirement
This package requires you to understand how does react
works in deep. It's not so hard. If I as python developer made it you can do it too.
Pre-requirements
As I told earlier this package continues the idea of @wrap-mutant/react. Be sure you have read the docs.
RenderedArray
Let's begin from minimal working example:
import React, { useContext, useCallback } from "react";
import { useWMState, createMutableContext } from "@wrap-mutant/react";
import { RenderedArray } from "@wrap-mutant/react-rendered-array/array";
type MyModel = {
// objects stored in your Array
};
type MyComponentProps = {
model: MyModel;
update: () => void;
doSmth: (arg: any) => void;
// other callbacks
};
const MyComponentCTX = createMutableContext({
update: () => {},
doSmth: (arg: any) => {},
});
const MyComponent = (props: MyComponentProps) => {
return <>{/* Just your component render. Avoid using contexts here */}</>;
};
const MyAdapter = (props: MyModel) => {
const ctx = useContext(MyComponentCTX); // DO NOT UNPACK IT
return (
<MyComponent
model={props}
update={() => ctx.update()} // DO NOT UNPACK IT
doSmth={(arg) => ctx.doSmth(arg)} // DO NOT UNPACK IT
/>
);
};
const recordFactory = RenderedArray({
Component: MyAdapter,
keyFunction: (item: MyModel) => item.key,
});
export const MyContainer = () => {
// Don't forget to pass `wrap: false`
const [records, updateRecords] = useWMState(recordFactory, { wrap: false });
// prettier-ignore
const update = useCallback(() => {/*whatever you need*/}, [/*deps*/]);
// prettier-ignore
const doSmth = useCallback((arg: any) => {/*whatever you need*/}, [/*deps*/]);
return (
<>
<MyComponentCTX.Provider value={{ update, doSmth }}>
{records.render()}
</MyComponentCTX.Provider>
</>
);
};
This example provides both @wrap-mutant/react's and current package's RenderedArray
APIs. But here we will talk about RenderedArray
:
-
Required options:
object
:-
Component
: Required react component to render eachArray
's element -
keyFunction
: Requiredfunction
generateskey
from yourArray
's element -
count
: Optionalnumber
parameter meaning how many wrapper objects will be pre-created. More info at @wrap-mutant/core API V2
-
-
Returns already wrapped into
Proxy
objectArray
. Then you may mutate it as you want. Supported methods:- Assingment by index, e.g.
myArray[42] = {...something}
- Delete by index, e.g.
delete myArray[42]
-
push
,pop
,shift
,unshift
,reverse
,splice
,sort
- Assingment by index, e.g.
RenderedHeap (TODO)
Requires to publish my fork of heap implementation
More info about heap data structure. Actually it means always sorted Array
. Very useful in graphics, but can be used everywhere you need always sorted data
Any questions?
Don't be afraid to open this library source code -- it's really small. Also we have Telegram Community