question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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 <Graphin> component. This is because @antv/graphin does not expose as an exportable GraphinProvider component.

Example / Scenario 1

Imagine I have a component called <NetworkTopologyViewer> which is responsible for setting up my <Graphin> component along with custom behavior

/**
* @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 (
	 <Card title="Network Topology">
		<Graphin {...GraphinProps....}>
                     <!- 😢 context data is only available in here. -->
	  	</Graphin>
      <Card>
  )
}

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.



Proposal

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

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

<GraphinProvider>
    <NetworkTopologyViewer />
</GraphinProvider>
    
// ---------OR initialize with data --------------
const graphinContextData = {...};
<GraphinProvider value={graphinContextData}>
   <NetworkTopologyViewer />
</GraphinProvider>



/**
* @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 <Graphin> 🎉
  
	return (
	 <Card title="Network Topology">
		<Graphin {...GraphinProps....}/>
      <Card>
  )
}

Benefits

  • adds more flexibility to the API
     const TopologyViewer = () => {
         const { graph, apis, isGraphinReady } = useGraphin();
         if (isGraphinReady === false) {
               return <SomeSkeletonLoader />; // skeleton component for good user experience https://ant.design/components/skeleton/
         }
        return (
          <Graphin> ...</Graphin>
        )
     }
    
  • 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().
       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 <Graphin> component loads, it will update the GraphinProvider’s context data
const graphinContextData = {...};

<GraphinProvider>
    <NetworkTopologyViewer />
</GraphinProvider>
    
// ---------OR initialize with data --------------
const graphinContextData = {...};
<GraphinProvider value={graphinContextData}>
   <NetworkTopologyViewer />
</GraphinProvider>

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.

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 (creator of react-query) talking about this pattern:

Kent C Dodds (creator or react-testing-library)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:4
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
timlrxcommented, Dec 15, 2021

It’s a nice idea! Currently for motif, we are just storing the ref from Graphin and passing it through to the other widget components using a provider. The other components can then useContext and have access to the full G6 api.

A useGraphin would help simplify things.

1reaction
mxz96102commented, Dec 20, 2021

I agree that deprecate class component will embrace more features of React 18, but for now, it might not be done in this version, considering that some of the users still depend on class lifecycle to do something, in this version using id might be enough for users, and for break change (like converting Graphin to function component), may happen in a new version like Graphin 3?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using the Effect Hook - React
They let you use state and other React features without writing a class. The Effect Hook lets you perform side effects in function...
Read more >
useHooks - Easy to understand React Hook recipes
This website provides easy to understand code examples to help you learn how hooks work and inspire you to take advantage of them...
Read more >
Useful React Hooks That You Can Use In Your Projects
We'll go through several code examples of each hook and also explore how you'd create a custom hook. Note: This tutorial requires a...
Read more >
How to fetch data with React Hooks - Robin Wieruch
If you just want to have a ready to go React Hook for data fetching: npm install use-data-api and follow the documentation. Don't...
Read more >
Understanding common frustrations with React Hooks
Let's get started! What problems do React Hooks solve? What was wrong with class components? Yet another JavaScript paradigm to learn; To hell ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found