{"id":13400782,"url":"https://github.com/sindresorhus/react-extras","last_synced_at":"2025-10-05T01:03:55.855Z","repository":{"id":28247583,"uuid":"117923759","full_name":"sindresorhus/react-extras","owner":"sindresorhus","description":"Useful components and utilities for working with React","archived":false,"fork":false,"pushed_at":"2023-06-12T17:39:38.000Z","size":59,"stargazers_count":722,"open_issues_count":0,"forks_count":39,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-01T00:34:04.166Z","etag":null,"topics":["npm-package","react","react-component","react-utils"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sindresorhus.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":"sindresorhus","open_collective":"sindresorhus","custom":"https://sindresorhus.com/donate"}},"created_at":"2018-01-18T02:57:57.000Z","updated_at":"2025-03-19T03:30:44.000Z","dependencies_parsed_at":"2023-09-24T03:51:20.852Z","dependency_job_id":null,"html_url":"https://github.com/sindresorhus/react-extras","commit_stats":{"total_commits":57,"total_committers":12,"mean_commits":4.75,"dds":"0.21052631578947367","last_synced_commit":"cc003a7da61ee80ec8a39d159610a4e7399cf15d"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Freact-extras","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Freact-extras/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Freact-extras/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindresorhus%2Freact-extras/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sindresorhus","download_url":"https://codeload.github.com/sindresorhus/react-extras/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247334209,"owners_count":20922164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["npm-package","react","react-component","react-utils"],"created_at":"2024-07-30T19:00:55.390Z","updated_at":"2025-10-05T01:03:55.847Z","avatar_url":"https://github.com/sindresorhus.png","language":"JavaScript","funding_links":["https://github.com/sponsors/sindresorhus","https://opencollective.com/sindresorhus","https://sindresorhus.com/donate"],"categories":["Uncategorized","JavaScript","🌐 Web Development - Frontend","React","React [🔝](#readme)"],"sub_categories":["Uncategorized","React Components"],"readme":"# react-extras\n\n\u003e Useful components and utilities for working with [React](https://reactjs.org)\n\n## Install\n\n```sh\nnpm install react-extras\n```\n\n## Usage\n\n```js\nimport React from 'react';\nimport {If} from 'react-extras';\n\nconst App = props =\u003e (\n\t\u003cIf condition={props.showUnicorn}\u003e\n\t\t\u003cdiv className=\"unicorn\"\u003e\n\t\t\t🦄\n\t\t\u003c/div\u003e\n\t\u003c/If\u003e\n);\n```\n\n## API\n\n### autoBind(self, options?)\n\nAutomatically binds your `React.Component` subclass methods to the instance. See the [`autoBind.react()` docs](https://github.com/sindresorhus/auto-bind#autobindreactself-options).\n\n### classNames(…input)\n\nConditionally join CSS class names together.\n\n#### input\n\nType: `string | object`\n\nAccepts a combination of strings and objects. Only object keys with truthy values are included. Anything else is ignored.\n\n```js\nimport {classNames} from 'react-extras';\n\nclassNames('unicorn', 'rainbow');\n//=\u003e 'unicorn rainbow'\n\nclassNames({awesome: true, foo: false}, 'unicorn', {rainbow: false});\n//=\u003e 'awesome unicorn'\n\nclassNames('unicorn', null, undefined, 0, 1, {foo: null});\n//=\u003e 'unicorn'\n\nconst buttonType = 'main';\nclassNames({[`button-${buttonType}`]: true});\n//=\u003e 'button-main'\n```\n\n```jsx\nimport {classNames} from 'react-extras';\n\nconst Button = props =\u003e {\n\tconsole.log(props);\n\t/*\n\t{\n\t\ttype: 'success',\n\t\tisBlock: false,\n\t\tisSmall: true\n\t}\n\t*/\n\n\tconst buttonClass = classNames(\n\t\t'button',\n\t\t{\n\t\t\t[`button-${props.type}`]: Boolean(props.type),\n\t\t\t'button-block': props.isBlock,\n\t\t\t'button-small': props.isSmall\n\t\t}\n\t);\n\n\tconsole.log(buttonClass);\n\t//=\u003e 'button button-success button-small'\n\n\treturn \u003cbutton className={buttonClass}\u003e…\u003c/button\u003e;\n};\n```\n\n### `\u003cIf\u003e`\n\nReact component that renders the children if the `condition` prop is `true`.\n\nBeware that even though the children are not rendered when the `condition` is `false`, they're still evaluated.\n\nIf you need it to not be evaluated on `false`, you can pass a function to the `render` prop that returns the children:\n\n```jsx\nimport {If} from 'react-extras';\n\n\u003cdiv\u003e\n\t\u003cIf condition={props.error} render={() =\u003e (\n\t\t\u003ch1\u003e{props.error}\u003c/h1\u003e\n\t)}/\u003e\n\u003c/div\u003e\n```\n\nOr you could just use plain JavaScript:\n\n```jsx\n\u003cdiv\u003e\n\t{props.error \u0026\u0026 (\n\t\t\u003ch1\u003e{props.error}\u003c/h1\u003e\n\t)}\n\u003c/div\u003e\n```\n\n### `\u003cChoose\u003e`\n\nReact component similar to a switch case. `\u003cChoose\u003e` has 2 children components:\n\n- `\u003cChoose.When\u003e` that renders the children if the `condition` prop is `true`.\n- `\u003cChoose.Otherwise\u003e` that renders the children if has no `\u003cChoose.When\u003e` with `true` prop `condition`.\n\nNote that even when the children are not rendered, they're still evaluated.\n\n```jsx\nimport {Choose} from 'react-extras';\n\n\u003cdiv\u003e\n\t\u003cChoose\u003e\n\t\t\u003cChoose.When condition={props.success}\u003e\n\t\t\t\u003ch1\u003e{props.success}\u003c/h1\u003e\n\t\t\u003c/Choose.When\u003e\n\t\t\u003cChoose.When condition={props.error}\u003e\n\t\t\t\u003ch1\u003e{props.error}\u003c/h1\u003e\n\t\t\u003c/Choose.When\u003e\n\t\t\u003cChoose.Otherwise\u003e\n\t\t\t\u003ch1\u003e😎\u003c/h1\u003e\n\t\t\u003c/Choose.Otherwise\u003e\n\t\u003c/Choose\u003e\n\u003c/div\u003e\n```\n\nOr you could just use plain JavaScript:\n\n```js\n\u003cdiv\u003e\n\t{(() =\u003e {\n\t\tif (props.success) {\n\t\t\treturn \u003ch1\u003e{props.success}\u003c/h1\u003e;\n\t\t}\n\n\t\tif (props.error) {\n\t\t\treturn \u003ch1\u003e{props.error}\u003c/h1\u003e;\n\t\t}\n\n\t\treturn \u003ch1\u003e😎\u003c/h1\u003e;\n\t})()}\n\u003c/div\u003e\n```\n\n### `\u003cFor/\u003e`\n\nReact component that iterates over the `of` prop and renders the `render` prop.\n\n```jsx\nimport {For} from 'react-extras';\n\n\u003cdiv\u003e\n\t\u003cFor of={['🌈', '🦄', '😎']} render={(item, index) =\u003e\n\t\t\u003cbutton key={index}\u003e{item}\u003c/button\u003e\n\t}/\u003e\n\u003c/div\u003e\n```\n\nOr you could just use plain JavaScript:\n\n```jsx\n\u003cdiv\u003e\n\t{['🌈', '🦄', '😎'].map((item, index) =\u003e\n\t\t\u003cbutton key={index}\u003e{item}\u003c/button\u003e\n\t)}\n\u003c/div\u003e\n```\n\n### `\u003cImage/\u003e`\n\nReact component that improves the `\u003cimg\u003e` element.\n\nIt makes the image invisible if it fails to load instead of showing the default broken image icon. Optionally, specify a fallback image URL.\n\n```jsx\nimport {Image} from 'react-extras';\n\n\u003cImage\n\turl=\"https://sindresorhus.com/unicorn.jpg\"\n\tfallbackUrl=\"https://sindresorhus.com/rainbow.jpg\"\n/\u003e\n```\n\nIt supports all the props that `\u003cimg\u003e` supports, but you use the prop `url` instead of `src`.\n\n### `\u003cRootClass/\u003e`\n\nRenderless React component that can add and remove classes to the root `\u003chtml\u003e` element. It accepts an `add` prop for adding classes, and a `remove` prop for removing classes. Both accept either a single class or multiple classes separated by space.\n\n```jsx\nimport {RootClass} from 'react-extras';\n\n\u003cIf condition={props.isDarkMode}\u003e\n\t\u003cRootClass add=\"dark-mode\"/\u003e\n\u003c/If\u003e\n```\n\n```jsx\nimport {RootClass} from 'react-extras';\n\n\u003cRootClass add=\"logged-in paid-user\" remove=\"promo\"/\u003e\n```\n\n### `\u003cBodyClass/\u003e`\n\nSame as `\u003cRootClass/\u003e` but for `\u003cbody\u003e`.\n\nPrefer `\u003cRootClass/\u003e` though, because it's nicer to put global classes on `\u003chtml\u003e` as you can consistently prefix everything with the class:\n\n```css\n.dark-mode body {\n\tbackground: #000;\n}\n\n.dark-mode a {\n\t…\n}\n```\n\nWith `\u003cBodyClass/\u003e` you need to do:\n\n```css\nbody.dark-mode {\n\tbackground: #000;\n}\n\n.dark-mode a {\n\t…\n}\n```\n\n### intersperse(children, separator?)\n\nInserts a separator between each element of the children.\n\n#### children\n\nType: `ReactNode`\n\nThe elements to intersperse with separators.\n\n#### separator\n\nType: `ReactNode | ((index: number, count: number) =\u003e ReactNode)`\\\nDefault: `', '`\n\nThe separator to insert between elements. Can be a React node or a function that returns a React node.\n\n```jsx\nimport {intersperse} from 'react-extras';\n\nconst items = ['Apple', 'Orange', 'Banana'];\nconst list = intersperse(\n\titems.map(item =\u003e \u003cli key={item}\u003e{item}\u003c/li\u003e),\n\t', '\n);\n// =\u003e [\u003cli\u003eApple\u003c/li\u003e, ', ', \u003cli\u003eOrange\u003c/li\u003e, ', ', \u003cli\u003eBanana\u003c/li\u003e]\n```\n\nWith a function separator:\n\n```jsx\nimport {intersperse} from 'react-extras';\n\nconst items = ['Apple', 'Orange', 'Banana'];\nconst list = intersperse(\n\titems.map(item =\u003e \u003cli key={item}\u003e{item}\u003c/li\u003e),\n\t(index, count) =\u003e index === count - 2 ? ' and ' : ', '\n);\n// =\u003e [\u003cli\u003eApple\u003c/li\u003e, ', ', \u003cli\u003eOrange\u003c/li\u003e, ' and ', \u003cli\u003eBanana\u003c/li\u003e]\n```\n\n### `\u003cJoin/\u003e`\n\nReact component that renders the children with a separator between each element.\n\n```jsx\nimport {Join} from 'react-extras';\n\n\u003cJoin\u003e\n\t\u003cli\u003eApple\u003c/li\u003e\n\t\u003cli\u003eOrange\u003c/li\u003e\n\t\u003cli\u003eBanana\u003c/li\u003e\n\u003c/Join\u003e\n// =\u003e \u003cli\u003eApple\u003c/li\u003e, \u003cli\u003eOrange\u003c/li\u003e, \u003cli\u003eBanana\u003c/li\u003e\n```\n\nWith a custom separator:\n\n```jsx\nimport {Join} from 'react-extras';\n\n\u003cJoin separator=\" | \"\u003e\n\t\u003ca href=\"#\"\u003eHome\u003c/a\u003e\n\t\u003ca href=\"#\"\u003eAbout\u003c/a\u003e\n\t\u003ca href=\"#\"\u003eContact\u003c/a\u003e\n\u003c/Join\u003e\n// =\u003e \u003ca href=\"#\"\u003eHome\u003c/a\u003e | \u003ca href=\"#\"\u003eAbout\u003c/a\u003e | \u003ca href=\"#\"\u003eContact\u003c/a\u003e\n```\n\nWith a function separator:\n\n```jsx\nimport {Join} from 'react-extras';\n\n\u003cJoin separator={(index, count) =\u003e index === count - 2 ? ' and ' : ', '}\u003e\n\t\u003cspan\u003eApple\u003c/span\u003e\n\t\u003cspan\u003eOrange\u003c/span\u003e\n\t\u003cspan\u003eBanana\u003c/span\u003e\n\u003c/Join\u003e\n// =\u003e \u003cspan\u003eApple\u003c/span\u003e, \u003cspan\u003eOrange\u003c/span\u003e and \u003cspan\u003eBanana\u003c/span\u003e\n```\n\n### isStatelessComponent(Component)\n\nReturns a boolean of whether the given `Component` is a [functional stateless component](https://javascriptplayground.com/functional-stateless-components-react/).\n\n### getDisplayName(Component)\n\nReturns the [display name](https://reactjs.org/docs/react-component.html#displayname) of the given `Component`.\n\n### canUseDOM\n\nA boolean of whether you're running in a context with a [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction). Can be used to check if your component is running in the browser or if it's being server-rendered.\n\n## Related\n\n- [react-router-util](https://github.com/sindresorhus/react-router-util) - Useful components and utilities for working with React Router\n- [sass-extras](https://github.com/sindresorhus/sass-extras) - Useful utilities for working with Sass\n- [class-names](https://github.com/sindresorhus/class-names) - Conditionally join CSS class names together\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Freact-extras","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsindresorhus%2Freact-extras","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindresorhus%2Freact-extras/lists"}