{"id":13660180,"url":"https://github.com/kudos-dude/react-best-practices","last_synced_at":"2025-04-24T19:30:39.078Z","repository":{"id":41506671,"uuid":"165725944","full_name":"kudos-dude/react-best-practices","owner":"kudos-dude","description":"A comprehensive reference guide to kickstart your React architecting career!","archived":false,"fork":false,"pushed_at":"2023-03-20T14:50:57.000Z","size":1,"stargazers_count":672,"open_issues_count":0,"forks_count":67,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-11-10T14:42:08.461Z","etag":null,"topics":["advanced","architecture","articles","beginner","best-practices","functional-programming","javascirpt","libraries","patterns","react","reactjs","redux","starter-project"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kudos-dude.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-01-14T19:57:57.000Z","updated_at":"2024-11-03T15:35:30.000Z","dependencies_parsed_at":"2024-01-10T22:10:27.529Z","dependency_job_id":"09f89bc4-fab3-4a62-8eb2-4edb99cdf994","html_url":"https://github.com/kudos-dude/react-best-practices","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudos-dude%2Freact-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudos-dude%2Freact-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudos-dude%2Freact-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kudos-dude%2Freact-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kudos-dude","download_url":"https://codeload.github.com/kudos-dude/react-best-practices/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250693443,"owners_count":21472265,"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":["advanced","architecture","articles","beginner","best-practices","functional-programming","javascirpt","libraries","patterns","react","reactjs","redux","starter-project"],"created_at":"2024-08-02T05:01:17.968Z","updated_at":"2025-04-24T19:30:38.796Z","avatar_url":"https://github.com/kudos-dude.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# React Best Practices\n\n## Architecture\n\n### Patterns\n\n**Flux Pattern (uni-directional)**  \nhttps://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207  \n\n### Functional Paradigm\n\n#### Functional Programming\n\n- [Immutability](https://medium.com/dailyjs/the-state-of-immutability-169d2cd11310)\n  - No side-effects\n  - Predictable data\n- [Functional methods](https://medium.com/dailyjs/the-state-of-immutability-169d2cd11310)\n  - map/filter/reduce\n    - [w3Schools array functions](https://www.w3schools.com/jsref/jsref_obj_array.asp)\n- [Higher Order Components/Functions](https://medium.freecodecamp.org/higher-order-components-the-ultimate-guide-b453a68bb851)\n  - Reusability and Composition\n\n#### Pure Components\n\n- fn(state, props) == UI\n- Local state suggestions from: https://medium.com/@robftw/characteristics-of-an-ideal-react-architecture-883b9b92be0b\n  - No local state other than:\n    - Animation/triggering of CSS Classes\n    - UI control that doesn't involve business logic or dependent on other components\n    - Extremely trivial UI related variables that won't cause side effects\n    - Standalone libraries\n\n### Routing\n\n**React Router**  \nhttps://github.com/ReactTraining/react-router\n\nGuide:  \nhttps://reacttraining.com/react-router/web/guides/quick-start\n\n### State Management\n\n**Redux**  \nhttps://redux.js.org/\n\n**Redux DevTools**  \n[Chrome Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en)\n\nThis is a must have for Redux development.\n\nGreat article if you want to hone your skills:  \nhttps://codeburst.io/redux-devtools-for-dummies-74566c597d7\n\n#### Middleware\n\n**Redux Thunk**  \nhttps://github.com/reduxjs/redux-thunk\n\n\"Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.\"\n\n**Redux-Sagas**  \nhttps://github.com/redux-saga/redux-saga\n\nSimilar concept to thunk using Middleware to control side-effects in a React-Redux application, but with the added bonus of using ES6 Generators to control async flow and increase readability.\n\n[More on Generators](https://redux-saga.js.org/docs/ExternalResources.html)\n\n### State Structure\n\nNormalized data structures by Id (Relational Table Model)\n\n```javascript\n{\n  entities: {\n    Post: {\n      itemById: {\n        \"post1\" : {\n          id: \"post1\"\n          author: \"author1\"\n          body: \"...\"\n          comments: [\"comment1\", \"comment2\"]\n        },\n        \"post2\" : {\n          id: \"post2\"\n          author: \"author2\"\n          body: \"...\"\n          comments: [\"comment3\", \"comment4\", \"comment5\"]\n        },\n      },\n      items: [\"post1\", \"post2\"],\n      meta: {},\n    },\n    User: {\n      itemsById: {\n        \"user1\": {\n          username: \"user1\",\n          name: \"User 1\",\n        },\n        \"user2\": {\n          username: \"user2\",\n          name: \"User 2\",\n        },\n        \"user3\": {\n          username: \"user3\",\n          name: \"User 3\",\n        },\n      },\n      items: [\"user1\", \"user2\", \"user3\"],\n      meta: {},\n    },\n    Comment: {\n      itemsById: {\n          \"comment1\": {\n            userId: \"user1\",\n            postId: \"post1\",\n            body: { ... },\n          },\n          \"comment2\": {\n            userId: \"user2\",\n            postId: \"post2\",\n            body: { ... },\n          },\n          \"comment3\": {\n            userId: \"user3\",\n            postId: \"post3\",\n            body: { ... },\n          },\n          \"comment4\": {\n            userId: \"user4\",\n            postId: \"post4\",\n            body: { ... },\n          },\n          \"comment5\": {\n            userId: \"user5\",\n            postId: \"post5\",\n            body: { ... },\n          },\n        },\n        items: [\"comment1\", \"comment2\", \"comment3\", \"comment4\", \"comment5\"],\n        meta: {}\n    },\n  },\n  \n  \n  simpleDomainData1: {...},\n  simpleDomainData2: {...},\n}\n```\n\nRemoves the deeply nested structures as your state grows in size and keeps components from re-rendering accidentally.\n\n### Folder Structure\n\n```\n.\n├── /android/\n├── /ios/\n|\n├── /assets\n│   ├── /fonts/\n│   ├── /images/\n│   ├── /videos/\n|\n├── /app or /src\n│   ├── /ducks/  // See \"Ducks\"\n│   ├── /scenes/\n│   |   ├── /App\n│   |   |   ├── /_/\n│   |   |   ├── /App.js\n│   |   |   └── /index.js\n|   |   ├── /MyScene/\n|   |   |   ├── /__tests__/\n|   |   |   ├── /_\n|   |   |   |   ├── /MySubcomponent\n|   |   |   |       ├── /__tests__/\n|   |   |   |       ├── /MySubcomponent.js\n│   |   |   |       └── /index.js\n│   |   |   ├── /MyScene.js\n│   |   |   └── /index.js\n│   ├── /shared/\n|   |   ├── /SharedAppSpecificComponent\n|   |   |   ├── /__tests__/\n|   |   |   ├── /SharedAppSpecificComponent.js\n|   |   |   └── /index.js\n│   |   └── /types.js\n|   ├── /store/ // configureStore.js + middleware\n|   └── /utils/ // helper functions, etc.\n|\n├── /lib\n|   ├── /Button\n|       ├── /__tests__/\n|       ├── /Button.js\n|       └── /index.js\n|\n├── /tools/  //Build scripts, other tools\n├── /node_modules/\n└── package.json\n```\n\nhttps://github.com/kylpo/react-playbook/blob/master/component-architecture/5_Example-App-Structure.md\n\n**/lib/ explanation:**\nEvery component that is not \"app specific\" or a *primitive component* can be a candidate to be moved to the /lib/ folder. This allows for the possible side effect of hand-rolling your own component library as you code!\n\nPrimitive components are those that take in only primitives as their props and are functionally pure.\n\n#### Redux \"Ducks\"\n\n```\n.\n├── /ducks/\n    ├── /MyDuck/\n    |   ├── /__tests__/\n    |   ├── actions.js\n    |   ├── index.js\n    |   ├── reducers.js\n    |   ├── selectors.js\n    |   ├── types.js\n    |   ├── urls.js\n    |   └── utils.js\n    ├── /utils/ // Reducer specific utils\n    ├── rootReducer.js\n    └── types.js\n```\n\nhttps://medium.freecodecamp.org/scaling-your-redux-app-with-ducks-6115955638be\n\n## Coding Style\n\n### Component Creation\n\n- Write a stateless functional component first\n  - if (component requires state or life-cycle) Consider Hooks\n  - if (component is comprised of multiple components or smaller pieces of functionality) Create container component\n  - Move shared components out\n    - if (app dependent) Keep in shared/MyComponent\n    - if (!app dependent or primitive) Move to lib folder\n- Avoid re-rendering component if possible\n\n## Styling\n\n**Semantic UI React**  \nhttps://github.com/Semantic-Org/Semantic-UI-React\n\nA JQuery-free version of Semantic UI that comes with React-based components. Semantic UI is great for themeing as well.\n\n## Testing\n\n### Libraries\n\n**Jest**  \nhttps://jestjs.io/\n\nMost popular React testing library. Comes with snapshot comparisons which is very useful for testing pure components.\n\n**Note:** Function spies are now included included in Jest, so I've removed `sinon` for now\n\n**Enzyme**  \nhttps://airbnb.io/enzyme/\n\nA popular addition to Jest that provides additional functionality to traversing through component trees,\nas well as helper functions for testing, triggering user events being an example.\n\n### Strategies\n\n**From:** https://github.com/kylpo/react-playbook/blob/master/best-practices/react.md\n\nWrite component tests that accomplish the following goals (from [Getting Started with TDD in React](https://semaphoreci.com/community/tutorials/getting-started-with-tdd-in-react?utm_source=javascriptweekly\u0026utm_medium=email))\n\n- It renders\n- It renders the correct thing\n  - Default props\n  - Varied props\n- It renders the different states\n- Test events\n- Test edge cases\n  - e.g. something that uses an array should be thrown an empty array\n\n## Build and Deploy\n\n### Starter kits\n\nhttps://reactjs.org/community/starter-kits.html\n\nThis list contains many popular choices, but your choice is yours. Getting a good starter kit depends entirely on what you're looking to get out of your project and team.\n\n### Build Libraries\n\n**Babel**  \nhttps://babeljs.io/\n\nTranspiles your javascript down from the latest standards to backwards compatible, browser friendly source. Used for transpiling JSX to JS.\n\n**Webpack**  \nhttps://webpack.js.org/\n\nBundles your files into static assets that are ready for production deploy. Many extensible plugins available.\n\n**ESLint**  \nhttps://eslint.org/\n\nKeeps your code nice and tidy by yelling at you with squigglies. You can link this to your IDE.\n\nGreat ESLint configs:  \n[prettier-eslint](https://github.com/prettier/prettier-eslint)  \n[eslint-config-airbnb](https://www.npmjs.com/package/eslint-config-airbnb)  \n\n## Source Control\n\n### Branch Naming Strategies\n\n**From:** http://www.guyroutledge.co.uk/blog/git-branch-naming-conventions/  \n\n`type/component-name/title`\n\nCommon Types:\n\n- feature\n- fix\n- hot-fix\n- refactor\n- update\n- upgrade\n- remove\n\nComponent Name example:  \n`login-form`\n\nTitle example:  \n`hoc-formik-input`\n\n## Libraries\n\n### Form Helpers\n\n**Formik**  \nhttps://github.com/jaredpalmer/formik\n\nCreates an ephemeral state held by its components that abstracts away all the boilerplate that goes into creating and maintaining forms.\n\n### State Management Helpers\n\n**Reselect**  \nhttps://github.com/reduxjs/reselect\n\nCreates a selector where the first functions passed in compute props for a final function. If none of those props have changed, then that function is not run and the result from the previous invocation is returned.\n\nThis keeps the state from needlessly causing components to re-render.\n\n### Styling\n\n**classnames**  \nhttps://github.com/JedWatson/classnames\n\nTakes in conditionals that returns a space-delimited string for className.\n\n```javascript\nimport classnames from 'classnames';\n\nlet classes = classnames('sd-date', {\n  current: date.month() === this.props.month,\n  future: date.month() \u003e this.props.month,\n  past: date.month() \u003c this.props.month\n});\n\nreturn (\n  \u003cbutton className={classes} /\u003e\n\n  vs\n\n  \u003cbutton className={`button-default-style ${isActive ? \"active\" : \"\"}`} /\u003e\n);\n```\n\n## IDEs\n\n**Visual Studio Code**  \nhttps://code.visualstudio.com/\n\nMicrosoft has opensourced this light-weight and highly extensible IDE. My personal favorite.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkudos-dude%2Freact-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkudos-dude%2Freact-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkudos-dude%2Freact-best-practices/lists"}