New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-routeways

Package Overview
Dependencies
Maintainers
0
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-routeways

Use ts-routeways and react-router-dom together

  • 1.4.0
  • latest
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

CI CodeQL Pages Release NPM version NPM bundle size NPM downloads NPM license GitHub Release Date Known Vulnerabilities

React Routeways

This is not another React routing library. Instead, it's a complete abstraction to use ts-routeways together with react-router-dom, providing all the type safety, url parsing/generation, and codecs definition of ts-routeways to the your react-router-dom routes, hooks, and components.

Install

React Routeways has some required peer dependencies:

DependencyVersion
react>=16.8.0
react-dom>=16.8.0
react-router-dom>=6.0.0
ts-routeways>=1.4.7

The React dependencies yopu should already have, so to install React Routeway you can:

With Yarn:

yarn add react-routeways ts-routeways react-router-dom

With NPM:

npm i react-routeways ts-routeways react-router-dom

Usage

React Routeways is basically a set of React hooks and components which you can use with your Routeways routes. The following are available:

You can also check the 📚 API Reference for more details and type definitions on each of the above.

Components

This set of components are mostly react-router-dom replacement drop-in components. The main difference is that wherever those components required a prop with a url/path string, now the will require a ts-routeways route instead.

A wrapper over react-router-dom's component, with the difference that the to prop expects a Routeway route instead of a path string. If the route requires path variables and/or query parameters, you can pass them over the params prop.

const { users } = MainRoutes;

export function HomeScreen(): ReactElement {

  return (
    <Link to={users.view} params={{ userId: 153 }}>
      {"Go to user 153"}
    </Link>
  );
}
Navigate

A wrapper over react-router-dom's component, with the difference that the to prop expects a Routeway route instead of a path string. If the route requires path variables and/or query parameters, you can pass them over the params prop.

const { home } = MainRoutes;

export function UserScreen(): ReactElement {

  return (
    <>
      {userId === undefined && (
        <Navigate to={home} />
      )}
    </>
  )
}

A wrapper over react-router-dom's component, with the difference that the to prop expects a Routeway route instead of a path string. If the route requires path variables and/or query parameters, you can pass them over the params prop.

const { users } = MainRoutes;

export function NavScreen(): ReactElement {

  return (
    <NavLink to={users} style={({ isActive }) => isActive ? activeStyle : undefined}>
      {"Go to user 153"}
    </Link>
  );
}
Route

Same as react-router-dom's component, but it replaces the path prop with route, where you can pass as Routeway route which will be used to create the path.

See the usage example in react-routeways' component.

Routes

A "wrapper" over react-router-dom's component which allows the use of react-routeways' components as children.

The route prop also allows a "*" literal string to match anything, and as a replacement of the splat segments support, you can use the catchAll prop, which basically appends a /* string to the end of the path.

import { BrowserRouter } from "react-router-dom";
import { Route, Routes } from "react-routeways";

const { home, users, settings } = MainRoutes;

export function MainNavigation(): ReactElement {

  return (
    <BrowserRouter>
      <Routes>
        <Route route="*" element={<NotFound />} />
        <Route route={home} element={<HomeScreen />} />
        <Route route={users} element={<UsersScreen />}>
          <Route route={users.view} catchAll={true} element={<ViewUserScreen />} />
          <Route route={users.edit} catchAll={true} element={<EditUserScreen />} />
        </Route>
        <Route route={settings} element={<SettingsScreen />}>
      </Routes>
    </BrowserRouter>
  )
}

Hooks

This is a set of hooks which provides a reactive way of using navigation, path variables, and query parameters. As well as the components, they are all based on Routeways routes instead of unsage string paths/urls. Another big advantage is that the path variables and query parameters hooks create react states which source of thruth is the current location. This means that updating path variables and/or query parameters states will reflect in other components using the same hook(s) with the same route, without the need of extra React providers.

createNavigatorHook

Creates a hook that returns a "Navigator" obeject from your custom routes. This provides natural experience of imperative navigation based on your routes structure.

const useNavigator = createNavigatorHook(MainRoutes);

export function HomeScreen(): ReactElement {
  const { logout, users } = useNavigator();

  useEffect(() => {
    if (session !== null) {
      logout.reset();
    } else {
      users.view.navigate({ userId: 463 });
    }
  }, [session]);

  return (
    // ...
  )
}
useNavigation

Returns an object which contains navigation functions that can be used along with Routeways routes. A big benefit of this hook is that provides te goTo and resetTo functions, which are stable callback versions of navigate and reset, so they are ideal to use on event-like props.

const { home, logout, users } = MainRoutes;

export function HomeScreen(): ReactElement {
  const { goTo, navigate, reset, resetTo } = useNavigation();

  useEffect(() => {
    if (session !== null) {
      reset(logout);
    } else {
      navigate(users.view, { userId: 463 });
    }
  }, [session]);

  return (
    <button onClick={goTo(users.edit, { userId: 463 })}>{"Edit User"}</button>
    <button onClick={resetTo(home)}>{"Go Home"}</button>
  )
}
usePathVars

Returns a tuple of a stateful value of the path variables, and a function to update them. Just like the useState hook would. However, because changing path variables means that the current location may also be different, an update to the path variables will produce a navigate using the updated values.

const { user } = MainRoutes;

export function EditUserScreen(): ReactElement {
  const [pathVars, setPathVars] = usePathVars(user.edit);

  const changeUser = useCallback((userId: number) => (): void => {
    setPathVars({ usertId });
  }, [setPathVars]);

  return (
    <div>
      <h2>{`Current User: ${pathVars.userId}`}</h2>

      <ul>
        {users.map(user => (
          <li key={user.id}>
            <button onClick={changeUser(user.id)}>{user.name}</button>
          </li>
        ))}
      </ul>
    </div>
  )
}
useQueryParam

Returns a tuple of a stateful value of the specified query param, and a function to update it. Just like the useState hook would. However, because the source of truth for this state is the current location, whenever the state is updated in one component, it will be also updated in other components using the same query param state. This keeps consistency across the state and the location all the time.

const { user } = MainRoutes;

export function ViewUserScreen(): ReactElement {
  const [page, setPage] = useQueryParam(user.view, "page", 1);
  const [search, setSearch] = useQueryParam(user.view, "search");

  const nextPage = useCallback((): void => {
    setPage(prev => prev + 1);
  }, [setPage]);

  const handleSearch = useCallback((value: string): void => {
    setSearch(value);
  }, [setSearch]);

  return (
    <div>
      <Pagination current={page} onNext={nextPage} />

      <SearchInput value={search} onChange={handleSearch} />
    </div>
  )
}
useQueryParameters

Returns a tuple of a stateful value of all query parameters, and a function to update them. Just like the useState hook would. However, because the source of truth for this state is the current location, whenever the state is updated in one component, it will be also updated in other components using the same state from this hook. This keeps consistency across the state and the location all the time.

const { user } = MainRoutes;

export function ViewUserScreen(): ReactElement {
  const [queryParams, setQueryParams] = useQueryParameters(user.view);

  const nextPage = useCallback((): void => {
    setQueryParams(prev => ({ ...prev, page: (prev.page ?? 0) + 1 }));
  }, [setQueryParams]);

  const handleSearch = useCallback((search: string): void => {
    setQueryParams({ page: 1, search });
  }, [setQueryParams]);

  return (
    <div>
      <Pagination current={queryParams.page ?? 1} onNext={nextPage} />

      <SearchInput value={queryParams.search} onChange={handleSearch} />
    </div>
  )
}
useRouteParams

Returns a tuple of a stateful value of both the path variables and query parameters, and a function to update them. Just like the useState hook would. This hook uses both usePathVars and useQueryParameters, so updating parameters may have the same effects as in both hooks.

const { user } = MainRoutes;

export function ViewUserScreen(): ReactElement {
  const [params, setParams] = useRouteParams(user.view);

  const nextPage = useCallback((): void => {
    setParams(prev => ({ ...prev, page: (prev.page ?? 0) + 1 }));
  }, [setParams]);

  const handleSearch = useCallback((search: string): void => {
    setParams(prev => ({ ...prev, page: 1, search }));
  }, [setParams]);

  useEffect(() => {
    fetchUserData(params.userId).then(() => ...);
  }, []);

  return (
    <div>
      <Pagination current={params.page ?? 1} onNext={nextPage} />

      <SearchInput value={params.search} onChange={handleSearch} />
    </div>
  )
}

Something's missing?

Suggestions are always welcome! Please create an issue describing the request, feature, or bug. I'll try to look into it as soon as possible 🙂

Contributions

Contributions are very welcome! To do so, please fork this repository and open a Pull Request against the main branch.

License

MIT License

Keywords

FAQs

Package last updated on 22 Jun 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc