βοΈ π¨οΈ A hierarchy sensitive, middleware-defined console.log
for React and React Native. β¨
- π Batteries included.
- π¦ Declare custom log types.
- πͺ Supports JSX-scoped filtering and functionality.
Using Yarn:
yarn add react-use-logs
By default, react-use-logs
exports a useLogs()
hook, which works pretty much just like your standard window.console
object:
import { useLogs } from "react-use-logs";
export default () => {
const logs = useLogs();
return <div onPress={() => logs.debug("Normal", "Old", { console: true })} />
};
It's possible to define custom handlers for particular calls to useLogs()
. First, wrap your application in a <LogsProvider />
:
import React from 'react';
import LogsProvider from 'react-use-logs';
export default () => (
<LogsProvider>
{/* TODO: awesome app here */}
</LogsProvider>
);
Once this is done, you can pass a custom middleware
prop, which is an array that accepts Middleware functions which take the following form:
function someMiddleware(level: string, messages: unknown[], next: () => void) {
// Do something with the message.
alert(...messages);
// Allow the next middleware in the chain to execute:
next();
}
Next, you can use the middleware as follows:
import React from 'react';
import LogsProvider from 'react-use-logs';
import { someMiddleware, someOtherMiddleware } from './middleware';
export default () => (
<LogsProvider middleware={[someMiddleware, someOtherMiddleware]}>
{/* TODO: awesome app here */}
</LogsProvider>
);
At this point any call to logs.debug
, for example, will instead get passed through the middleware chain.
Notice: By default, a
LogsProvider
will use the default builtin logging mechanism, theLogLevel
middleware. This is based onloglevel
. However, if you override themiddleware
prop for a root-levelLogsProvider
, this will not be included by default. You can reintroduce the standard console behaviour by including theLogLevel
middleware exported by the library.
It's also possible to declare specific middleware for different parts of the DOM tree. This is achieved by nesting a child LogsProvider
, and declaring an additional middleware
prop. The middleware supplied here will be appended to the global middleware.
import React from 'react';
import LogsProvider, { LogLevel } from 'react-use-logs';
import { someMiddleware, someOtherMiddleware } from './middleware';
export default () => (
<LogsProvider middleware={[LogLevel, someMiddleware]}>
<LogsProvider middleware={[someOtherMiddleware]}>
{/* TODO: some special logging route here */}
</LogsProvider>
{/* TODO: awesome app here */}
</LogsProvider>
);
By default, react-use-logs
uses the existing window.console export format, i.e:
import { useLogs } from "react-use-logs";
const logs = useLogs();
logs.trace("");
logs.debug("");
logs.info("");
logs.warn("");
logs.error("");
By using a custom LogsProvider
, you can specify an additional levels
prop to declare custom log levels:
import React from 'react';
import LogsProvider from 'react-use-logs';
export default () => (
<LogsProvider levels={["good", "bad", "ugly"]}>
{/* TODO: awesome app here */}
</LogsProvider>
);
This will result in useLogs
returning an object like so:
import { useLogs } from "react-use-logs";
const logs = useLogs();
logs.good("");
logs.bad("");
logs.ugly("");
Notice Similar to
middleware
, for a root-levelLogsProvider
a definedlevels
prop will override the original default levels. For nested providers, the contents of thelevels
will be appended to the inherited ones.
You can specify a level
prop to a LogsProvider
to declare the minimum actionable level, which obeys prioritized order. In the example below, it is only possible for warn
and error
events to be executed; all other invocations will be ignored.
import React from 'react';
import LogsProvider from 'react-use-logs';
export default () => (
<LogsProvider level="warn">
{/* TODO: silent app here */}
</LogsProvider>
);
In addition, you can disable logging altogether for any child component by passing a disabled
prop:
import React from 'react';
import LogsProvider from 'react-use-logs';
export default () => (
<LogsProvider disabled>
{/* TODO: silent app here */}
</LogsProvider>
);
By default, LogsProvider
s operate in Strict Mode. This has the following effect:
- A
disabled
LogsProvider
will disable logging for all children in the tree. - The selected
level
of theLogsProvider
will serve as the minimum log level for nested children.
Although deterministic, this is not useful for debugging. This is because it is sometimes useful to temporarily activate logging for select portion of a silenced log tree. To enable nested LogProvider
s to ignore a parent's configuration, you can disable strict mode by passing a strict={false}
prop:
<>
<Logs disabled strict={false}>
{/* because the parent is not strict, we can enable the child tree */}
<Logs disabled={false}>
</Logs>
</Logs>
<Logs level="warn" strict={false}>
{/* because the parent is not strict, we can log more granular information */}
<Logs level="trace">
</Logs>
</Logs>
</>