{"id":13485054,"url":"https://github.com/romac/react-if","last_synced_at":"2025-05-13T21:10:40.052Z","repository":{"id":20367004,"uuid":"23642304","full_name":"romac/react-if","owner":"romac","description":"🌗 Render React components conditionally","archived":false,"fork":false,"pushed_at":"2025-04-13T13:51:17.000Z","size":22633,"stargazers_count":1108,"open_issues_count":3,"forks_count":55,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-19T17:42:22.462Z","etag":null,"topics":["react"],"latest_commit_sha":null,"homepage":"https://romac.github.io/react-if/","language":"TypeScript","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/romac.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-09-04T00:12:05.000Z","updated_at":"2025-04-13T22:57:57.000Z","dependencies_parsed_at":"2023-01-16T21:46:17.317Z","dependency_job_id":"60e792b7-7fec-4814-b347-ca7a63212af1","html_url":"https://github.com/romac/react-if","commit_stats":{"total_commits":523,"total_committers":30,"mean_commits":"17.433333333333334","dds":0.6175908221797324,"last_synced_commit":"5efd9ef2a5df70046d7e73f9b82c9a43e5f48c29"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romac%2Freact-if","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romac%2Freact-if/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romac%2Freact-if/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romac%2Freact-if/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romac","download_url":"https://codeload.github.com/romac/react-if/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251326825,"owners_count":21571633,"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":["react"],"created_at":"2024-07-31T17:01:44.375Z","updated_at":"2025-04-28T14:05:04.215Z","avatar_url":"https://github.com/romac.png","language":"TypeScript","readme":"# React If\n\n[![npm](https://img.shields.io/npm/v/react-if?logo=npm)](https://www.npmjs.com/package/react-if)\n[![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-if?label=bundle%20size\u0026logo=webpack)](https://bundlephobia.com/result?p=react-if)\n[![Continuous Integration](https://github.com/romac/react-if/workflows/Continuous%20Integration/badge.svg)](https://github.com/romac/react-if/actions)\n[![Issues](http://img.shields.io/github/issues/romac/react-if.svg?style=flat\u0026logo=github\u0026logoColor=959DA5\u0026labelColor=2D3339)](https://github.com/romac/react-if/issues)\n[![License](https://img.shields.io/github/license/romac/react-if?logo=github\u0026logoColor=959DA5\u0026labelColor=2D3339)](https://github.com/romac/react-if/blob/master/LICENSE.md)\n[![Contact](https://img.shields.io/badge/contact-@__romac-blue.svg?style=flat\u0026logo=twitter)](https://twitter.com/_romac)\n[![Contact](https://img.shields.io/badge/contact-@favna__-blue.svg?style=flat\u0026logo=twitter)](https://twitter.com/fanva_)\n\nRender React components conditionally.\n\n## What does this component do\n\nTake a look at the following presentational component, which contains a commonly used pattern for conditional rendering:\n\n```jsx\nconst Bar = ({ name, age, drinkingAge }) =\u003e (\n  \u003cdiv\u003e\n    \u003cHeader /\u003e\n    {age \u003e= drinkingAge ? \u003cspan className=\"ok\"\u003eHave a beer, {name}!\u003c/span\u003e : \u003cspan className=\"not-ok\"\u003eSorry, {name}, you are not old enough.\u003c/span\u003e}\n    \u003cFooter /\u003e\n  \u003c/div\u003e\n);\n```\n\nWith `React-If` you can rewrite this into a more readable, expressive format:\n\n```jsx\nconst Bar = ({ name, age, drinkingAge }) =\u003e (\n  \u003cdiv\u003e\n    \u003cHeader /\u003e\n    \u003cIf condition={age \u003e= drinkingAge}\u003e\n      \u003cThen\u003e\n        \u003cspan className=\"ok\"\u003eHave a beer, {name}!\u003c/span\u003e\n      \u003c/Then\u003e\n      \u003cElse\u003e\n        \u003cspan className=\"not-ok\"\u003eSorry, {name}, you are not old enough.\u003c/span\u003e\n      \u003c/Else\u003e\n    \u003c/If\u003e\n    \u003cFooter /\u003e\n  \u003c/div\u003e\n);\n```\n\n## Delaying evaluation of children / condition\n\nIt is important to note that, because JavaScript is an eagerly evaluated language, children of both the `Then` and `Else` component and condition will be evaluated regardless of the value of the condition. Should that be an issue for performance reasons, one can wrap said children / condition in a [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), to delay evaluation of the children / condition, as in the following example:\n\n```jsx\nconst renderData = (data) =\u003e {\n  val computed = /* expensive computation */\n  return \u003cspan\u003eHere is the result: {computed}\u003c/span\u003e;\n};\n\nconst Foo = ({ data }) =\u003e (\n    \u003cdiv\u003e\n        \u003cIf condition={false}\u003e\n            \u003cThen\u003e{() =\u003e\n              renderData(data)\n            }\u003c/Then\u003e\n            \u003cElse\u003e\n              Nothing to see here\n            \u003c/Else\u003e\n        \u003c/If\u003e\n        \u003cIf condition={!props.bears}\u003e\n          \u003cThen\u003e\n            No bears\n          \u003c/Then\u003e\n\n          \u003cElse\u003e\n            \u003cIf condition={() =\u003e props.bears.length}\u003e\n              Empty bears array\n            \u003c/If\u003e\n            \u003cElse\u003e\n              // Display bears\n            \u003c/Else\u003e\n          \u003c/Else\u003e\n        \u003c/If\u003e\n    \u003c/div\u003e\n)\n```\n\nBy doing so, `renderData` will not be called in the 1st example.\n\nAnd `props.bears.length` will not be called in the 2nd example.\n\n## Installing and usage\n\n### NPM:\n\n`npm install react-if`\nOr with yarn: `yarn add react-if`\n\n```jsx\n// ES2015\nimport { If, Then, Else, When, Unless, Switch, Case, Default } from 'react-if';\n\n// CommonJS:\nconst { If, Then, Else, When, Unless, Switch, Case, Default } = require('react-if');\n```\n\n## Examples\n\n## Switch/Case/Default\n\n```jsx\nimport React from 'react';\nimport { Switch, Case, Default } from 'react-if';\n\nconst myNumber = 3;\n\nconst Example = () =\u003e (\n  \u003cdiv\u003e\n    \u003cSwitch\u003e\n      \u003cCase condition={myNumber === 9}\u003eThis will be displayed if condition is matched\u003c/Case\u003e\n      \u003cCase condition={myNumber \u003e 1}\u003eThis will be displayed if condition is matched\u003c/Case\u003e\n      \u003cDefault\u003eThis will be displayed if no Case have matching condition\u003c/Default\u003e\n    \u003c/Switch\u003e\n  \u003c/div\u003e\n);\n```\n\n## Shorthands: When and Unless\n\n```jsx\nimport React from 'react';\nimport { When, Unless } from 'react-if';\n\nconst someCondition = false;\n\nconst Example = () =\u003e (\n  \u003cdiv\u003e\n    \u003cWhen condition={someCondition}\u003eThis will only be displayed, if the condition is TRUE\u003c/When\u003e\n  \u003c/div\u003e\n);\n\nconst AnotherExample = () =\u003e (\n  \u003cdiv\u003e\n    \u003cUnless condition={someCondition}\u003eThis will only be displayed, if the condition is FALSE\u003c/Unless\u003e\n  \u003c/div\u003e\n);\n```\n\n## Asynchronous condition\n\n```jsx\nimport React from 'react';\nimport { If, Fallback, Then, Else } from 'react-if';\n\nconst Example = () =\u003e {\n  const fetchData = () =\u003e {\n    // Return promise\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cIf condition={fetchData()}\u003e\n        \u003cFallback\u003eLoading data ...\u003c/Fallback\u003e\n        \u003cThen\u003e\n          {(data) =\u003e (\n            \u003cspan\u003eHere is your data: {data}\u003c/span\u003e\n          )}\n        \u003c/Then\u003e\n        \u003cElse\u003e\n          {(error) =\u003e (\n            \u003cspan\u003eFailed to load data because \"{error}\"\u003c/span\u003e\n          )}\n        \u003c/Else\u003e\n      \u003c/If\u003e\n    \u003c/div\u003e\n  );\n});\n```\n\n## API\n\n**_Note: For a fully auto-generated API, see [the github pages website](https://romac.github.io/react-if)_**\n\n### \u0026lt;If /\u0026gt;\n\n| Property    | Type            | Default |\n| ----------- | --------------- | ------- |\n| `condition` | Boolean/Promise |         |\n| `keepAlive` | Boolean         | false   |\n\nIf `condition` evaluates to `true`, renders the `\u003cThen /\u003e` block will be rendered, otherwise renders the `\u003cElse /\u003e` block. Either block may be omitted.\n\nThis component can contain any number of `\u003cThen /\u003e` or `\u003cElse /\u003e` blocks, but only the first block of the right type (either `Then` or `Else`, depending on the condition) will be rendered.\n\nWhen passing a Promise to `condition`, renders the `Fallback` block while the Promise is pending, the `\u003cThen /\u003e` block once Promise is resolved, and the `\u003cElse /\u003e` block when Promise is rejected.\nThe return value of the `Promise` can be retrieved within the `\u003cThen /\u003e` and `\u003cElse /\u003e` blocks; a render function must be child of these blocks.\n\n```jsx\n\u003cThen\u003e{(returnValue, promiseHistory, cancellablePromise) =\u003e \u003cspan\u003e{returnValue}\u003c/span\u003e}\u003c/Then\u003e\n```\n\nThe parameters of this render function are:\n\n- `returnValue`: The return value of the `Promise` (for the `\u003cThen /\u003e` block) or the error (for the `\u003cElse /\u003e` block);\n- `promiseHistory`: an Array of all the Promises that were ever passed to `\u003cIf /\u003e`. It contains cancellablePromise Objects, that have a promise, as well as a `cancel` method used to cancel the promise;\n- `cancellablePromise`: the cancellablePromise Object containing the promise that caused the rendering of this `\u003cThen /\u003e|\u003cElse /\u003e` block;\n\nIf the `keepAlive` prop evaluates to `false`, each rerender of the `\u003cIf /\u003e` component will automatically ignore the previous Promise if it was still pending.\n\n### \u0026lt;Then /\u0026gt;\n\nCan contain any number of elements inside, which it renders as-is. It can also contain a function. Should not be used outside of an `\u003cIf /\u003e` block. It will only be displayed, if parent `If` block's condition is true.\n\n### \u0026lt;Else /\u0026gt;\n\nCan contain any number of elements inside, which it renders as-is. It can also contain a function. Should not be used outside of an `\u003cIf /\u003e` block. It will only be displayed, if parent `If` block's condition is false.\n\n### \u0026lt;Switch /\u0026gt;\n\nA container for `\u003cCase condition={...}/\u003e` and `\u003cDefault /\u003e` blocks. It will render **the first matching** `Case`, or **the first encountered** `Default` (, or null).\n\n### \u0026lt;Case /\u0026gt;\n\n| Property    | Type    |\n| ----------- | ------- |\n| `condition` | Boolean |\n\nIf the `Case` is the first one to have its `condition` evaluates to `true` inside the parent `\u003cSwitch /\u003e` it will be the only rendered.\n\n### \u0026lt;Default /\u0026gt;\n\nIf no `Case` have its `condition` evaluates to `true` inside the parent `\u003cSwitch /\u003e`, the first `Default` will be the only one rendered.\n\n### \u0026lt;When /\u0026gt;\n\nA shorthand for `\u003cIf condition={...}\u003e\u003cThen\u003e...\u003c/Then\u003e\u003c/If\u003e`. The same rules apply to the child elements as with using the `Then` block.\n\n### \u0026lt;Unless /\u0026gt;\n\nA shorthand for `\u003cIf condition={...}\u003e\u003cElse\u003e...\u003c/Else\u003e\u003c/If\u003e`. The same rules apply to the child elements as with using the `Else` block.\n\n## License\n\n**React If** is released under the [MIT license](http://romac.mit-license.org).\n\n## Contributors\n\nPlease make sure to read the [Contributing Guide][contributing] before making a pull request.\n\nThank you to all the people who already contributed to react-if!\n\n\u003ca href=\"https://github.com/romac/react-if/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=romac/react-if\" /\u003e\n\u003c/a\u003e\n\n[contributing]: https://github.com/romac/react-if/blob/master/.github/CONTRIBUTING.md\n","funding_links":[],"categories":["TypeScript","React Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromac%2Freact-if","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromac%2Freact-if","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromac%2Freact-if/lists"}