score:0

You can write a Issues context provider that will provide {issues,useIssues} where issues are the issues and useIssues is a function that takes {user,repo}.

export const Issues = React.createContext();
export default ({ children }) => {
  const [issues, setIssues] = useState([]);
  const useIssues = ({ user, repo }) => {
    useEffect(() => {
      axios
        .get(
          `https://api.github.com/repos/${user}/${repo}/issues`
        )
        .then(response => {
          setIssues(response.data);
        })
        .catch(err => console.log(err));
    }, [user, repo]);
    return issues;
  };
  return (
    <Issues.Provider value={{ issues, useIssues }}>
      {children}
    </Issues.Provider>
  );
};

The component that has all the components that need issues can import this issues provider:

import IssuesProvider from './IssuesProvider';
export default () => (
  <IssuesProvider>
    <ComponentThatNeedsIssues />
    <ComponentThatSetsAndGetsIssues />
  </IssuesProvider>
);

For a component that needs to set issues you can get useIssues from context:

const { useIssues } = useContext(Issues);
const issues = useIssues({user,repo});

For a component that only needs issues:

const { issues } = useContext(Issues);

To see it all work together there is a codepen here

score:2

You are right by saying you need React.Context to handle this situation.

  1. You need to wrap your components into this context.
import React from "react";

const IssuesStateContext = React.createContext();
const IssuesDispatchContext = React.createContext();

function issuesReducer(state, action) {
  switch (action.type) {
    case "setIssues": {
      return [...action.payload];
    }

    default: {
      throw new Error(`Unhandled action type: ${action.type}`);
    }
  }
}

function IssuesProvider({ children }) {
  const [state, dispatch] = React.useReducer(issuesReducer, []);
  return (
    <IssuesStateContext.Provider value={state}>
      <IssuesDispatchContext.Provider value={dispatch}>
        {children}
      </IssuesDispatchContext.Provider>
    </IssuesStateContext.Provider>
  );
}

function useIssuesState() {
  const context = React.useContext(IssuesStateContext);
  if (context === undefined) {
    throw new Error("useIssuesState must be used within a IssuesProvider");
  }
  return context;
}
function useIssuesDispatch() {
  const context = React.useContext(IssuesDispatchContext);
  if (context === undefined) {
    throw new Error("useIssuesDispatch must be used within a IssuesProvider");
  }
  return context;
}

export { IssuesProvider, useIssuesState, useIssuesDispatch };

By using this separation in context you will be able to set issues coming from github in one component and render them in a completely different one.

Example:

App.js

ReactDOM.render(
  <IssuesProvider>
    <Component1 />
    <Component2 />
  </IssuesProvider>
)

Component 1

import React from 'react'
import { useIssuesDispatch } from './issues-context'

function Component1() {
  const dispatch = useIssuesDispatch()
  // fetch issues
  // .then dispatch({ type: 'setIssues', payload: response })

  // render
}

Component 2

import React from 'react'
import { useIssuesState } from './issues-context'

function Component2() {
  const issues = useIssuesState()

  // if issues.length > 0 ? render : null
}

Related Query

More Query from same tag