score:1

Accepted answer

You could go with solution to have context and have all wrapped components to access it with useContext hook.

This is how you can use it:

App component

import React, { Component, useState } from 'react';
import Nav from './Nav';
import Main from './Main';

const AppContext = createContext({
  executeNavigationFunction: () => {},
  setExecuteNavigationFunction: (navFunction: () => void) => {},
});
const App = () => {
  const [executeNavigationFunction, setExecuteNavigationFunction] = useState(() => {});

  return (
    <AppContext.Provider value={{ executeNavigationFunction, setExecuteNavigationFunction }}>
      <Nav />
      <Main />
    </AppContext.Provider>
  );
};

export default App;

Nav component

import React, {useEffect, useContext, useEffect} from 'react';
import { NavLink } from 'react-router-dom';
import AppContext from 'app';

const Nav = (props) => {
  const { setExecuteNavigationFunction } = useContext(AppContext);

  function doSomethingToNav() {
    // here's where I want to change appearance or do whatever to the nav
    // I want to be able to use this function from within my Nav component
    // but also want to be able to call it from any another component
  }

  useEffect(() => {
    setExecuteNavigationFunction(doSomethingToNav)
  }, [setExecuteNavigationFunction])

  return (
    <nav>
      <NavLink to="/pageone">Page One</NavLink>
      <NavLink to="/pagetwo">Page Two</NavLink>
    </nav>
  );
};

export default Nav;

PageOneItem component

import React, {useEffect, useContext} from 'react';
import { Link } from 'react-router-dom';
import AppContext from 'app';

const PageOneDetail = (props) => {
  const { executeNavigationFunction } = useContext(AppContext);

  useEffect(() => {
    executeNavigationFunction();
  }, []);
  return (
    <div>
      <Link to="/pageone">Close</Link>
      // I want to call doSomethingToNav function when I close this component. // Close, in this case, is just routing
      back to /pageone
      <p>Some content...</p>
    </div>
  );
};

export default PageOneDetail;

In this way you can use any data from any part of the app in any part of the app.

It may seem a bit hacky, but if you are not using some global state lib, Context is the way to go.


Related Query

More Query from same tag