antvis / antvis/Graphin

NEED FEEDBACK - Feature Idea -- Exportable GraphinProvider & useGraphin() react hook to access data from GraphinContext

Open
#333 10 comments 4 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
1.1k
Forks
275
PR merge metrics
No merged PRs in 30d

Description

Hi Graphin team & community,
I would like your opinion on this feature proposal for the library.

## Problem Statement
Currently, there is no way to access the `GraphinContext` data outside of the `` component.
This is because `@antv/graphin` does not expose as an exportable `GraphinProvider` component.

#### Example / Scenario 1
Imagine I have a component called `` which is responsible for setting up my `` component along with custom behavior

```tsx
/**
* @description
* Renders a Graph wrapped in a custom container
* and also sets up custom node behavior
*/
const NetworkTopologyViewer = () => {
const { graph } = React.useContext(GraphinContext); //❗ does not work. GraphinContext is not inside of a Provider
const handleNodeClick = e => {
console.log(e.item.getModel();
makeAPICall(e.item.getModel()))
}

// ❗ Cannot setup custom node behavior here because `graph` cannot be grabbed from context above
graph.on('node:click', handleNodeClick)

return (





)
}
```
This is a live code example of what I'm trying to achieve above, which is to define a `handleClick` event for when a node in my graph gets clicked.
- https://stackblitz.com/edit/react-ts-bgsybt?file=component%2Findex.ts



## Proposal
Expose a `useGraphin` hook, which allows us get & set data from the `GraphinContext`.

```tsx
// --------------------App.tsx--------
// Initialize with no data
import { GraphinProvider } from '@antv/graphin'
const graphinContextData = {...};


// ---------OR initialize with data --------------
const graphinContextData = {...};

/**
* @description
* Renders a Graph wrapped in a custom container
* and also sets up custom node behavior
*/
const NetworkTopologyViewer = () => {
const { graph, api} = useGraphin(); ✅ does not error because this component is inside a Provider in a parent component
const handleNodeClick = e => {.....})

graph.on('node:click', handleNodeClick) // I can setup my node behavior outside of 🎉

return (



)
}
```

## Benefits
- adds more flexibility to the API
```tsx
const TopologyViewer = () => {
const { graph, apis, isGraphinReady } = useGraphin();
if (isGraphinReady === false) {
return ; // skeleton component for good user experience https://ant.design/components/skeleton/
}
return (
...
)
}
```
- no more need to import `GraphinContext` since the `useGraphin()` hook can get or set data from the `GraphinContext`
- you would be able to use the `useGraphin()` hook inside of other hooks custom hooks.
- This would enable us to keep our component code a lot simpler; business logic could be encapsulated in inside custom hooks thanks to the help of `useGrapin()`.
```tsx
function myCustomHook(){
const {graph, apis} = useGraphin()
// I can easily put business logic code here .......I can manipulate the state of my graph & Graphin context here.
// this would could update GraphinProvider & update areas of my user interfance
}
```
- eliminates the need to have custom wrappers and containers. With the `useGraphin` hook, I can access all the data I need from any component wrapped by the `GraphinProvider`.
- easier to write test for the code

## Steps required to implement `useGraphin` in `@antv/graphin`

1. We would need to make `GraphinProvider` component & make it exportable to allow user's to wrap their component(s) with `GraphinProvider
- By default if no data is passed into `GraphinProvider` the data will be empty, but after `` component loads, it will update the `GraphinProvider`'s context data
```tsx
const graphinContextData = {...};


// ---------OR initialize with data --------------
const graphinContextData = {...};

```

## Example Fake Demo
Demo 1: https://stackblitz.com/edit/react-ts-cuhbx2?file=App.tsx
CleanShot 2021-12-05 at 17 50 22@2x

Demo2:
This demonstrates the hook pattern I'm describing (_to grab data from context data with hook_), which is a common API pattern. This example show a `useAuth()` to demonstrate the concept described broadly.
- https://stackblitz.com/edit/react-ts-p8dg9n?file=App.tsx
CleanShot 2021-12-05 at 17 55 56@2x

### References
This react pattern of using a hook to get & set data from the context is often called the "_Action hooks pattern_". It's nice and flexible & quite popular in newer react libraries like `react-query`, `react-router` etc.
[Tanner Linsley](https://twitter.com/tannerlinsley) (creator of `react-query`) talking about this pattern:
- https://www.youtube.com/watch?v=J-g9ZJha8FE&t=1s
- https://www.youtube.com/watch?v=JRz-xMIyPUA

[Kent C Dodds](https://twitter.com/kentcdodds?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor) (creator or [react-testing-library](https://github.com/kentcdodds))
- https://kentcdodds.com/blog/authentication-in-react-applications

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.