Skip to content

Commit d68b530

Browse files
committed
chore: improve nodes persistance
1 parent faefd7b commit d68b530

File tree

7 files changed

+624
-583
lines changed

7 files changed

+624
-583
lines changed

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"url": "git+https://github.com/fjmorant/react-native-nested-listview.git"
2222
},
2323
"dependencies": {
24-
"object-hash": "3.0.0",
25-
"use-global-hook": "0.3.0"
24+
"object-hash": "3.0.0"
2625
},
2726
"peerDependencies": {
2827
"react": "*",
@@ -41,16 +40,16 @@
4140
"@types/react-native": "0.67.2",
4241
"@types/react-test-renderer": "17.0.1",
4342
"@types/use-global-hook": "0.1.5",
44-
"@typescript-eslint/parser": "5.13.0",
45-
"babel-jest": "26.6.3",
43+
"@typescript-eslint/parser": "5.14.0",
44+
"babel-jest": "27.5.1",
4645
"codecov": "3.8.3",
4746
"eslint": "7.32.0",
4847
"eslint-plugin-prettier": "4.0.0",
4948
"husky": "7.0.4",
5049
"istanbul": "0.4.5",
5150
"istanbul-api": "3.0.0",
5251
"istanbul-reports": "3.1.4",
53-
"jest": "26.6.3",
52+
"jest": "27.5.1",
5453
"metro-react-native-babel-preset": "0.69.0",
5554
"prettier": "2.5.1",
5655
"prettier-eslint": "13.0.0",

src/nested-list-view/nested-list-view.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import hashObjectGenerator from 'object-hash';
22
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
33
import { StyleSheet, Text, View } from 'react-native';
44
import { INode, NodeView } from '../node-view';
5+
import { NodeProvider } from '../nodes-context-provider';
56

67
const styles = StyleSheet.create({
78
errorContainer: {
@@ -155,15 +156,17 @@ const NestedListView: React.FC<IProps> = React.memo(
155156
}
156157

157158
return (
158-
<NodeView
159-
getChildrenName={_getChildrenName}
160-
node={_root}
161-
onNodePressed={onNodePressed}
162-
level={0}
163-
renderNode={renderNode}
164-
extraData={extraData}
165-
keepOpenedState={keepOpenedState}
166-
/>
159+
<NodeProvider>
160+
<NodeView
161+
getChildrenName={_getChildrenName}
162+
node={_root}
163+
onNodePressed={onNodePressed}
164+
level={0}
165+
renderNode={renderNode}
166+
extraData={extraData}
167+
keepOpenedState={keepOpenedState}
168+
/>
169+
</NodeProvider>
167170
);
168171
},
169172
);

src/node-view/node-view.tsx

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
22
import { FlatList, Pressable } from 'react-native';
3-
import globalHook, { Store } from 'use-global-hook';
4-
import { GlobalState, INode, NodeActions } from './types';
3+
import { useNodesContext } from '../nodes-context-provider';
4+
import { INode } from './types';
55

66
export interface IProps {
77
getChildrenName: (item: INode) => string;
@@ -18,24 +18,6 @@ export interface IProps {
1818
keepOpenedState?: boolean;
1919
}
2020

21-
const actions = {
22-
setOpenedNode: (
23-
store: Store<GlobalState, NodeActions>,
24-
{ internalId, opened }: any,
25-
) => {
26-
store.setState({
27-
nodesState: { ...store.state.nodesState, [internalId]: opened },
28-
});
29-
},
30-
};
31-
32-
const initialState: GlobalState = {
33-
nodesState: { root: true },
34-
};
35-
36-
// @ts-ignore
37-
const useGlobal = globalHook<GlobalState, NodeActions>(initialState, actions);
38-
3921
const NodeView: React.FC<IProps> = React.memo(
4022
({
4123
renderNode,
@@ -46,13 +28,13 @@ const NodeView: React.FC<IProps> = React.memo(
4628
onNodePressed,
4729
keepOpenedState,
4830
}) => {
49-
const [globalState, globalActions]: [any, any] = useGlobal();
31+
const { openedNodes, setOpenNode } = useNodesContext();
5032

5133
const [_node, setNode]: [INode, any] = useState({
5234
...node,
5335
opened:
54-
keepOpenedState && globalState?.nodesState[node._internalId]
55-
? !!globalState?.nodesState[node._internalId]
36+
keepOpenedState && openedNodes[node._internalId]
37+
? !!openedNodes[node._internalId]
5638
: !!node.opened,
5739
});
5840

@@ -65,7 +47,7 @@ const NodeView: React.FC<IProps> = React.memo(
6547

6648
const _onNodePressed = useCallback(() => {
6749
if (keepOpenedState) {
68-
globalActions.setOpenedNode({
50+
setOpenNode({
6951
internalId: _node._internalId,
7052
opened: !_node.opened,
7153
});
@@ -79,7 +61,7 @@ const NodeView: React.FC<IProps> = React.memo(
7961
if (onNodePressed) {
8062
onNodePressed(_node);
8163
}
82-
}, [_node, globalActions, keepOpenedState, onNodePressed]);
64+
}, [_node, keepOpenedState, onNodePressed, setOpenNode]);
8365

8466
const renderChildren = useCallback(
8567
(item: INode, _level: number): ReactElement => (
@@ -107,8 +89,7 @@ const NodeView: React.FC<IProps> = React.memo(
10789
const nodeChildren: [] = _node[nodeChildrenName];
10890

10991
const isNodeOpened =
110-
(keepOpenedState && globalState?.nodesState[node._internalId]) ||
111-
_node.opened;
92+
(keepOpenedState && openedNodes[node._internalId]) || _node.opened;
11293

11394
return (
11495
<>

src/node-view/types.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
import { Store } from 'use-global-hook';
2-
31
export interface INode {
42
_internalId: string;
53
hidden: boolean;
64
opened: boolean;
75
[key: string]: any;
86
}
9-
10-
export interface GlobalState {
11-
nodesState: { root: boolean };
12-
}
13-
14-
export interface NodeActions {
15-
setOpenedNode: (
16-
store: Store<GlobalState, NodeActions>,
17-
{ internalId, opened }: any,
18-
) => void;
19-
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './nodes-context-provider';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React, { useContext, useRef } from 'react';
2+
3+
type SetOpenedNodesParams = {
4+
internalId: string;
5+
opened: boolean;
6+
};
7+
8+
type INodexContext = {
9+
openedNodes: { [name: string]: boolean };
10+
setOpenNode: ({ internalId, opened }: SetOpenedNodesParams) => void;
11+
};
12+
13+
const NodesContext = React.createContext<INodexContext>({
14+
openedNodes: {},
15+
setOpenNode: (_: SetOpenedNodesParams) => {},
16+
});
17+
18+
export const useNodesContext = () => useContext(NodesContext);
19+
20+
const NodeProvider = ({ children }: React.PropsWithChildren<{}>) => {
21+
const nodesOpenedRef = useRef({ root: true });
22+
23+
const setOpenNode = ({ internalId, opened }: SetOpenedNodesParams) => {
24+
nodesOpenedRef.current = {
25+
...nodesOpenedRef.current,
26+
[internalId]: opened,
27+
};
28+
};
29+
30+
return (
31+
<NodesContext.Provider
32+
value={{ openedNodes: nodesOpenedRef.current, setOpenNode }}>
33+
{children}
34+
</NodesContext.Provider>
35+
);
36+
};
37+
38+
export { NodeProvider };

0 commit comments

Comments
 (0)