├── .vscode ├── launch.json └── settings.json ├── README.md ├── _config.yml ├── assets ├── Higher-Order-Components.jpg ├── component-tree.png ├── context-api.jpg ├── dom.png ├── flux-2.png ├── flux-architecture.png ├── flux-structure.png ├── flux.png ├── mvc.png ├── poketimes-project.png ├── props-state.jpg ├── react-architecture.png ├── react-dev-tools.png ├── react-features.png ├── react-fiber.png ├── react-form.png ├── react-hooks.png ├── react-lifecycle.png ├── react-native-architecture.jpg ├── react-redux-form.png ├── react-redux.png ├── react-roadmap.png ├── react-routing.png ├── react-sight.png ├── react-store.png ├── react-twoway-data-binding.png ├── reconciliation.jpg ├── redux-2.png ├── redux-and-flux.png ├── redux-architecture.png ├── redux-components.jpg ├── redux-cycle.png ├── redux-data-flow.gif ├── redux-saga.png ├── redux-state.png ├── redux-thunk.jpeg ├── redux-workflow.png ├── redux.png ├── shadow-dom.png ├── star.png ├── todo-project.png ├── useLayoutEffect.png └── virtualdom-vs-realdom.png ├── best-practices.md ├── jest-quick-reference.md ├── react-quick-reference.md └── redux-quick-reference.md /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "chrome", 9 | "request": "launch", 10 | "name": "Launch Chrome against localhost", 11 | "url": "http://localhost:8080", 12 | "webRoot": "${workspaceFolder}" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /assets/Higher-Order-Components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/Higher-Order-Components.jpg -------------------------------------------------------------------------------- /assets/component-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/component-tree.png -------------------------------------------------------------------------------- /assets/context-api.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/context-api.jpg -------------------------------------------------------------------------------- /assets/dom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/dom.png -------------------------------------------------------------------------------- /assets/flux-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/flux-2.png -------------------------------------------------------------------------------- /assets/flux-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/flux-architecture.png -------------------------------------------------------------------------------- /assets/flux-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/flux-structure.png -------------------------------------------------------------------------------- /assets/flux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/flux.png -------------------------------------------------------------------------------- /assets/mvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/mvc.png -------------------------------------------------------------------------------- /assets/poketimes-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/poketimes-project.png -------------------------------------------------------------------------------- /assets/props-state.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/props-state.jpg -------------------------------------------------------------------------------- /assets/react-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-architecture.png -------------------------------------------------------------------------------- /assets/react-dev-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-dev-tools.png -------------------------------------------------------------------------------- /assets/react-features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-features.png -------------------------------------------------------------------------------- /assets/react-fiber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-fiber.png -------------------------------------------------------------------------------- /assets/react-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-form.png -------------------------------------------------------------------------------- /assets/react-hooks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-hooks.png -------------------------------------------------------------------------------- /assets/react-lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-lifecycle.png -------------------------------------------------------------------------------- /assets/react-native-architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-native-architecture.jpg -------------------------------------------------------------------------------- /assets/react-redux-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-redux-form.png -------------------------------------------------------------------------------- /assets/react-redux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-redux.png -------------------------------------------------------------------------------- /assets/react-roadmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-roadmap.png -------------------------------------------------------------------------------- /assets/react-routing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-routing.png -------------------------------------------------------------------------------- /assets/react-sight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-sight.png -------------------------------------------------------------------------------- /assets/react-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-store.png -------------------------------------------------------------------------------- /assets/react-twoway-data-binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/react-twoway-data-binding.png -------------------------------------------------------------------------------- /assets/reconciliation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/reconciliation.jpg -------------------------------------------------------------------------------- /assets/redux-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-2.png -------------------------------------------------------------------------------- /assets/redux-and-flux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-and-flux.png -------------------------------------------------------------------------------- /assets/redux-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-architecture.png -------------------------------------------------------------------------------- /assets/redux-components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-components.jpg -------------------------------------------------------------------------------- /assets/redux-cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-cycle.png -------------------------------------------------------------------------------- /assets/redux-data-flow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-data-flow.gif -------------------------------------------------------------------------------- /assets/redux-saga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-saga.png -------------------------------------------------------------------------------- /assets/redux-state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-state.png -------------------------------------------------------------------------------- /assets/redux-thunk.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-thunk.jpeg -------------------------------------------------------------------------------- /assets/redux-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux-workflow.png -------------------------------------------------------------------------------- /assets/redux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/redux.png -------------------------------------------------------------------------------- /assets/shadow-dom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/shadow-dom.png -------------------------------------------------------------------------------- /assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/star.png -------------------------------------------------------------------------------- /assets/todo-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/todo-project.png -------------------------------------------------------------------------------- /assets/useLayoutEffect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/useLayoutEffect.png -------------------------------------------------------------------------------- /assets/virtualdom-vs-realdom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krishnakiriti04/react-interview-questions/b19d5a7a3e90272ec9bbc6b89f08b079dbaec111/assets/virtualdom-vs-realdom.png -------------------------------------------------------------------------------- /best-practices.md: -------------------------------------------------------------------------------- 1 | # React Best Practices 2 | 3 | 1. Component name must start with capitals letters. 4 | 5 | 2. All the component must be small and function-specific. 6 | 7 | 3. All the component must have small description 8 | 9 | ```js 10 | /** 11 | * 12 | * Author: {...} 13 | * Description: {...} 14 | * Dependencies: {...} 15 | * 16 | **/ 17 | const SampleComponent = () => { 18 | 19 | return ( 20 |
21 | Sample Component ! 22 |
23 | ); 24 | } 25 | 26 | export default SampleComponent; 27 | ``` 28 | 29 | 4. All code must follow es6 coding standards. 30 | 31 | 5. For variables that are NOT constants or constructors, multi-word variables and functions SHOULD be lowerCamelCased. 32 | 33 | 6. Constants:- Pre-defined constants SHOULD be all-uppercase, and words separated by underscores: UPPER_UNDERSCORED. 34 | 35 | 7. Typeof:- In type comparisons, the value tested MUST NOT be wrapped in parenthesis and use triple equals to. 36 | 37 | ```js 38 | if (typeof myVariable === 'string') { 39 | // ... 40 | } 41 | ``` 42 | 43 | 8. In simple condition, Ternary operator should be used instead of if else statement. 44 | 45 | ```js 46 | // If-else Statement 47 | if(condition) { 48 | //... 49 | } else { 50 | //... 51 | } 52 | 53 | // Ternary operator 54 | let myVariable = condition ? exprIfTrue : exprIfFalse 55 | ``` 56 | 57 | 9. fragments should be used instead of container div. 58 | 59 | ```js 60 | ... 61 | 62 | render() { 63 | return ( 64 | 65 | Some text. 66 |

A heading

67 | More text. 68 |

Another heading

69 | Even more text. 70 |
71 | ); 72 | } 73 | ``` 74 | 75 | 10. All files related to any one component should be in a single folder 76 | 77 | 11. Functional components should be favored if we do not need to make use of React state. 78 | 79 | 12. Anonymous functions should not be used as handlers. 80 | 81 | 13. Inline styles should not be used inside component. 82 | 83 | 14. For a component to hide itself return null from render. 84 | 85 | 15. Higher Order Components should be used for cross-cutting concerns. 86 | 87 | 16. Prefer state initialization in class member variable declaration over constructor 88 | 89 | 17. Index should not be used as a key 90 | 91 | 18. Short-Circuit evaluation should be used in jsx 92 | 93 | ```js 94 | // Avoid 95 | const sampleComponent = () => { 96 | return isTrue ?

True!

: null 97 | }; 98 | 99 | // Recommended: short-circuit evaluation 100 | const sampleComponent = () => { 101 | return isTrue &&

True!

102 | }; 103 | ``` 104 | -------------------------------------------------------------------------------- /jest-quick-reference.md: -------------------------------------------------------------------------------- 1 | # Jest Quick Reference 2 | 3 | - [Test structure](#test-structure) 4 | - [Matchers](#matchers) 5 | - [Basic matchers](#basic-matchers) 6 | - [Truthiness](#truthiness) 7 | - [Numbers](#numbers) 8 | - [Strings](#strings) 9 | - [Arrays](#arrays) 10 | - [Objects](#objects) 11 | - [Exceptions](#exceptions) 12 | - [Snapshots](#snapshots) 13 | - [Mock functions](#mock-functions) 14 | - [Misc](#misc) 15 | - [Promise matchers (Jest 20+)](#promise-matchers-jest-20) 16 | - [Async tests](#async-tests) 17 | - [async/await](#asyncawait) 18 | - [Promises](#promises) 19 | - [done() callback](#done-callback) 20 | - [Mocks](#mocks) 21 | - [Mock functions](#mock-functions-1) 22 | - [Returning, resolving and rejecting values](#Returning-resolving-and-rejecting-values) 23 | - [Mock modules using `jest.mock` method](#mock-modules-using-jestmock-method) 24 | - [Mock modules using a mock file](#mock-modules-using-a-mock-file) 25 | - [Mock object methods](#mock-object-methods) 26 | - [Mock getters and setters (Jest 22.1.0+)](#mock-getters-and-setters-jest-2210) 27 | - [Mock getters and setters](#mock-getters-and-setters) 28 | - [Clearing and restoring mocks](#clearing-and-restoring-mocks) 29 | - [Accessing the original module when using mocks](#accessing-the-original-module-when-using-mocks) 30 | - [Timer mocks](#timer-mocks) 31 | - [Data-driven tests (Jest 23+)](#data-driven-tests-jest-23) 32 | - [Skipping tests](#skipping-tests) 33 | - [Testing modules with side effects](#testing-modules-with-side-effects) 34 | 35 | ## Basic Test Structure 36 | 37 | ```js 38 | describe('Color Picker', () => { 39 | beforeAll(() => { 40 | /* Runs before all tests */ 41 | }) 42 | afterAll(() => { 43 | /* Runs after all tests */ 44 | }) 45 | beforeEach(() => { 46 | /* Runs before each test */ 47 | }) 48 | afterEach(() => { 49 | /* Runs after each test */ 50 | }) 51 | 52 | test('Choose a color', () => { 53 | const actual = fn(['Alice', 'Bob', 'Eve']) 54 | expect(actual).toEqual(['Pink Alice', 'Pink Bob', 'Pink Eve']) 55 | }) 56 | }) 57 | ``` 58 | 59 | ## Matchers 60 | 61 | [Using matchers](http://jestjs.io/docs/en/using-matchers), [matchers docs](https://facebook.github.io/jest/docs/expect.html) 62 | 63 | ### Basic matchers 64 | 65 | ```js 66 | expect(42).toBe(42) // Strict equality (===) 67 | expect(42).not.toBe(3) // Strict equality (!==) 68 | expect([1, 2]).toEqual([1, 2]) // Deep equality 69 | expect({ a: undefined, b: 2 }).toEqual({ b: 2 }) // Deep equality 70 | expect({ a: undefined, b: 2 }).not.toStrictEqual({ b: 2 }) // Strict equality (Jest 23+) 71 | ``` 72 | 73 | ### Truthiness 74 | 75 | ```js 76 | // Matches anything that an if statement treats as true (not false, 0, '', null, undefined, NaN) 77 | expect('foo').toBeTruthy() 78 | // Matches anything that an if statement treats as false (false, 0, '', null, undefined, NaN) 79 | expect('').toBeFalsy() 80 | // Matches only null 81 | expect(null).toBeNull() 82 | // Matches only undefined 83 | expect(undefined).toBeUndefined() 84 | // The opposite of toBeUndefined 85 | expect(7).toBeDefined() 86 | // Matches true or false 87 | expect(true).toEqual(expect.any(Boolean)) 88 | ``` 89 | 90 | ### Numbers 91 | 92 | ```js 93 | expect(2).toBeGreaterThan(1) 94 | expect(1).toBeGreaterThanOrEqual(1) 95 | expect(1).toBeLessThan(2) 96 | expect(1).toBeLessThanOrEqual(1) 97 | expect(0.2 + 0.1).toBeCloseTo(0.3, 5) 98 | expect(NaN).toEqual(expect.any(Number)) 99 | ``` 100 | 101 | ### Strings 102 | 103 | ```js 104 | expect('long string').toMatch('str') 105 | expect('string').toEqual(expect.any(String)) 106 | expect('coffee').toMatch(/ff/) 107 | expect('pizza').not.toMatch('coffee') 108 | expect(['pizza', 'coffee']).toEqual([expect.stringContaining('zz'), expect.stringMatching(/ff/)]) 109 | ``` 110 | 111 | ### Arrays 112 | 113 | ```js 114 | expect([]).toEqual(expect.any(Array)) 115 | expect(['Alice', 'Bob', 'Eve']).toHaveLength(3) 116 | expect(['Alice', 'Bob', 'Eve']).toContain('Alice') 117 | expect([{ a: 1 }, { a: 2 }]).toContainEqual({ a: 1 }) 118 | expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(['Alice', 'Bob'])) 119 | ``` 120 | 121 | ### Objects 122 | 123 | ```js 124 | expect({ a: 1 }).toHaveProperty('a') 125 | expect({ a: 1 }).toHaveProperty('a', 1) 126 | expect({ a: { b: 1 } }).toHaveProperty('a.b') 127 | expect({ a: 1, b: 2 }).toMatchObject({ a: 1 }) 128 | expect({ a: 1, b: 2 }).toMatchObject({ 129 | a: expect.any(Number), 130 | b: expect.any(Number) 131 | }) 132 | expect([{ a: 1 }, { b: 2 }]).toEqual([ 133 | expect.objectContaining({ a: expect.any(Number) }), 134 | expect.anything() 135 | ]) 136 | ``` 137 | 138 | ### Exceptions 139 | 140 | ```js 141 | // const fn = () => { throw new Error('Out of cheese!') } 142 | expect(fn).toThrow() 143 | expect(fn).toThrow('Out of cheese') 144 | expect(fn).toThrowErrorMatchingSnapshot() 145 | ``` 146 | 147 | ### Snapshots 148 | 149 | ```js 150 | expect(node).toMatchSnapshot() 151 | // Jest 23+ 152 | expect(user).toMatchSnapshot({ 153 | date: expect.any(Date) 154 | }) 155 | expect(user).toMatchInlineSnapshot() 156 | ``` 157 | 158 | ### Mock functions 159 | 160 | ```js 161 | // const fn = jest.fn() 162 | // const fn = jest.fn().mockName('Unicorn') -- named mock, Jest 22+ 163 | expect(fn).toBeCalled() // Function was called 164 | expect(fn).not.toBeCalled() // Function was *not* called 165 | expect(fn).toHaveBeenCalledTimes(1) // Function was called only once 166 | expect(fn).toBeCalledWith(arg1, arg2) // Any of calls was with these arguments 167 | expect(fn).toHaveBeenLastCalledWith(arg1, arg2) // Last call was with these arguments 168 | expect(fn).toHaveBeenNthCalledWith(args) // Nth call was with these arguments (Jest 23+) 169 | expect(fn).toHaveReturnedTimes(2) // Function was returned without throwing an error (Jest 23+) 170 | expect(fn).toHaveReturnedWith(value) // Function returned a value (Jest 23+) 171 | expect(fn).toHaveLastReturnedWith(value) // Last function call returned a value (Jest 23+) 172 | expect(fn).toHaveNthReturnedWith(value) // Nth function call returned a value (Jest 23+) 173 | expect(fn.mock.calls).toEqual([['first', 'call', 'args'], ['second', 'call', 'args']]) // Multiple calls 174 | expect(fn.mock.calls[0][0]).toBe(2) // fn.mock.calls[0][0] — the first argument of the first call 175 | ``` 176 | 177 |
178 | Aliases 179 | 180 | - `toBeCalled` → `toHaveBeenCalled` 181 | - `toBeCalledWith` → `toHaveBeenCalledWith` 182 | - `lastCalledWith` → `toHaveBeenLastCalledWith` 183 | - `nthCalledWith` → `toHaveBeenNthCalledWith` 184 | - `toReturnTimes` → `toHaveReturnedTimes` 185 | - `toReturnWith` → `toHaveReturnedWith` 186 | - `lastReturnedWith` → `toHaveLastReturnedWith` 187 | - `nthReturnedWith` → `toHaveNthReturnedWith` 188 |
189 | 190 | ### Misc 191 | 192 | ```js 193 | expect(new A()).toBeInstanceOf(A) 194 | expect(() => {}).toEqual(expect.any(Function)) 195 | expect('pizza').toEqual(expect.anything()) 196 | ``` 197 | 198 | ### Promise matchers (Jest 20+) 199 | 200 | ```js 201 | test('resolve to lemon', () => { 202 | expect.assertions(1) 203 | // Make sure to add a return statement 204 | return expect(Promise.resolve('lemon')).resolves.toBe('lemon') 205 | return expect(Promise.reject('octopus')).rejects.toBeDefined() 206 | return expect(Promise.reject(Error('pizza'))).rejects.toThrow() 207 | }) 208 | ``` 209 | 210 | Or with async/await: 211 | 212 | ```js 213 | test('resolve to lemon', async () => { 214 | expect.assertions(2) 215 | await expect(Promise.resolve('lemon')).resolves.toBe('lemon') 216 | await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus') 217 | }) 218 | ``` 219 | 220 | [resolves docs](https://facebook.github.io/jest/docs/en/expect.html#resolves) 221 | 222 | ## Async tests 223 | 224 | See [more examples](https://facebook.github.io/jest/docs/en/tutorial-async.html) in Jest docs. 225 | 226 | It’s a good practice to specify a number of expected assertions in async tests, so the test will fail if your assertions weren’t called at all. 227 | 228 | ```js 229 | test('async test', () => { 230 | expect.assertions(3) // Exactly three assertions are called during a test 231 | // OR 232 | expect.hasAssertions() // At least one assertion is called during a test 233 | 234 | // Your async tests 235 | }) 236 | ``` 237 | Note that you can also do this per file, outside any `describe` and `test`: 238 | ```js 239 | beforeEach(expect.hasAssertions) 240 | ``` 241 | This will verify the presense of at least one assertion per test case. It also plays nice with more specific `expect.assertions(3)` declarations. 242 | 243 | ### async/await 244 | 245 | ```js 246 | test('async test', async () => { 247 | expect.assertions(1) 248 | const result = await runAsyncOperation() 249 | expect(result).toBe(true) 250 | }) 251 | ``` 252 | 253 | ### Promises 254 | 255 | _Return_ a Promise from your test: 256 | 257 | ```js 258 | test('async test', () => { 259 | expect.assertions(1) 260 | return runAsyncOperation().then(result => { 261 | expect(result).toBe(true) 262 | }) 263 | }) 264 | ``` 265 | 266 | ### done() callback 267 | 268 | Wrap your assertions in try/catch block, otherwise Jest will ignore failures: 269 | 270 | ```js 271 | test('async test', done => { 272 | expect.assertions(1) 273 | runAsyncOperation() 274 | setTimeout(() => { 275 | try { 276 | const result = getAsyncOperationResult() 277 | expect(result).toBe(true) 278 | done() 279 | } catch (err) { 280 | done.fail(err) 281 | } 282 | }) 283 | }) 284 | ``` 285 | 286 | ## Mocks 287 | 288 | ### Mock functions 289 | 290 | ```js 291 | test('call the callback', () => { 292 | const callback = jest.fn() 293 | fn(callback) 294 | expect(callback).toBeCalled() 295 | expect(callback.mock.calls[0][1].baz).toBe('pizza') // Second argument of the first call 296 | // Match the first and the last arguments but ignore the second argument 297 | expect(callback).toHaveBeenLastCalledWith('meal', expect.anything(), 'margarita'); 298 | }) 299 | ``` 300 | 301 | You can also use snapshots: 302 | 303 | ```js 304 | test('call the callback', () => { 305 | const callback = jest.fn().mockName('Unicorn') // mockName is available in Jest 22+ 306 | fn(callback) 307 | expect(callback).toMatchSnapshot() 308 | // -> 309 | // [MockFunction Unicorn] { 310 | // "calls": Array [ 311 | // ... 312 | }) 313 | ``` 314 | 315 | And pass an implementation to `jest.fn` function: 316 | 317 | ```js 318 | const callback = jest.fn(() => true) 319 | ``` 320 | 321 | [Mock functions docs](https://facebook.github.io/jest/docs/mock-function-api.html) 322 | 323 | ### Returning, resolving and rejecting values 324 | 325 | Your mocks can return values: 326 | 327 | ```js 328 | const callback = jest.fn().mockReturnValue(true); 329 | const callbackOnce = jest.fn().mockReturnValueOnce(true); 330 | ``` 331 | 332 | Or resolve values: 333 | 334 | ```js 335 | const promise = jest.fn().mockResolvedValue(true); 336 | const promiseOnce = jest.fn().mockResolvedValueOnce(true); 337 | ``` 338 | 339 | They can even reject values: 340 | 341 | ```js 342 | const failedPromise = jest.fn().mockRejectedValue("Error"); 343 | const failedPromiseOnce = jest.fn().mockRejectedValueOnce("Error"); 344 | ``` 345 | 346 | You can even combine these: 347 | 348 | ```js 349 | const callback = jest.fn() 350 | .mockReturnValueOnce(false) 351 | .mockReturnValue(true); 352 | 353 | // -> 354 | // call 1: false 355 | // call 2+: true 356 | ``` 357 | 358 | ### Mock modules using `jest.mock` method 359 | 360 | ```js 361 | jest.mock('lodash/memoize', () => a => a) // The original lodash/memoize should exist 362 | jest.mock('lodash/memoize', () => a => a, { virtual: true }) // The original lodash/memoize isn’t required 363 | ``` 364 | 365 | [jest.mock docs](https://facebook.github.io/jest/docs/jest-object.html#jestmockmodulename-factory-options) 366 | 367 | > Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block. Use `jest.doMock` if you want to explicitly avoid this behavior. 368 | 369 | ### Mock modules using a mock file 370 | 371 | 1. Create a file like `__mocks__/lodash/memoize.js`: 372 | 373 | ```js 374 | module.exports = a => a 375 | ``` 376 | 377 | 2. Add to your test: 378 | 379 | ```js 380 | jest.mock('lodash/memoize') 381 | ``` 382 | 383 | > Note: When using `babel-jest`, calls to `jest.mock` will automatically be hoisted to the top of the code block. Use `jest.doMock` if you want to explicitly avoid this behavior. 384 | 385 | [Manual mocks docs](https://facebook.github.io/jest/docs/manual-mocks.html) 386 | 387 | ### Mock object methods 388 | 389 | ```js 390 | const spy = jest.spyOn(console, 'log').mockImplementation(() => {}) 391 | expect(console.log.mock.calls).toEqual([['dope'], ['nope']]) 392 | spy.mockRestore() 393 | ``` 394 | 395 | ```js 396 | const spy = jest.spyOn(ajax, 'request').mockImplementation(() => Promise.resolve({ success: true })) 397 | expect(spy).toHaveBeenCalled() 398 | spy.mockRestore() 399 | ``` 400 | 401 | ### Mock getters and setters (Jest 22.1.0+) 402 | 403 | ```js 404 | const location = {} 405 | const getTitle = jest.spyOn(location, 'title', 'get').mockImplementation(() => 'pizza') 406 | const setTitle = jest.spyOn(location, 'title', 'set').mockImplementation(() => {}) 407 | ``` 408 | 409 | ### Mock getters and setters 410 | 411 | ```js 412 | const getTitle = jest.fn(() => 'pizza') 413 | const setTitle = jest.fn() 414 | const location = {} 415 | Object.defineProperty(location, 'title', { 416 | get: getTitle, 417 | set: setTitle 418 | }) 419 | ``` 420 | 421 | ### Clearing and restoring mocks 422 | 423 | For one mock: 424 | 425 | ```js 426 | fn.mockClear() // Clears mock usage date (fn.mock.calls, fn.mock.instances) 427 | fn.mockReset() // Clears and removes any mocked return values or implementations 428 | fn.mockRestore() // Resets and restores the initial implementation 429 | ``` 430 | 431 | > Note: `mockRestore` works only with mocks created by `jest.spyOn`. 432 | 433 | For all mocks: 434 | 435 | ```js 436 | jest.clearAllMocks() 437 | jest.resetAllMocks() 438 | jest.restoreAllMocks() 439 | ``` 440 | 441 | ### Accessing the original module when using mocks 442 | 443 | ```js 444 | jest.mock('fs') 445 | const fs = require('fs') // Mocked module 446 | const fs = require.requireActual('fs') // Original module 447 | ``` 448 | 449 | ### Timer mocks 450 | 451 | Write synchronous test for code that uses native timer functions (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`). 452 | 453 | ```js 454 | // Enable fake timers 455 | jest.useFakeTimers() 456 | 457 | test('kill the time', () => { 458 | const callback = jest.fn() 459 | 460 | // Run some code that uses setTimeout or setInterval 461 | const actual = someFunctionThatUseTimers(callback) 462 | 463 | // Fast-forward until all timers have been executed 464 | jest.runAllTimers() 465 | 466 | // Check the results synchronously 467 | expect(callback).toHaveBeenCalledTimes(1) 468 | }) 469 | ``` 470 | 471 | Or adjust timers by time with [advanceTimersByTime()](https://jestjs.io/docs/en/timer-mocks#advance-timers-by-time): 472 | 473 | ```js 474 | // Enable fake timers 475 | jest.useFakeTimers() 476 | 477 | test('kill the time', () => { 478 | const callback = jest.fn() 479 | 480 | // Run some code that uses setTimeout or setInterval 481 | const actual = someFunctionThatUseTimers(callback) 482 | 483 | // Fast-forward for 250 ms 484 | jest.advanceTimersByTime(250) 485 | 486 | // Check the results synchronously 487 | expect(callback).toHaveBeenCalledTimes(1) 488 | }) 489 | ``` 490 | 491 | Use [jest.runOnlyPendingTimers()](https://jestjs.io/docs/en/timer-mocks#run-pending-timers) for special cases. 492 | 493 | **Note:** you should call `jest.useFakeTimers()` in your test case to use other fake timer methods. 494 | 495 | ## Data-driven tests (Jest 23+) 496 | 497 | Run the same test with different data: 498 | 499 | ```js 500 | test.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])('.add(%s, %s)', (a, b, expected) => { 501 | expect(a + b).toBe(expected) 502 | }) 503 | ``` 504 | 505 | Or the same using template literals: 506 | 507 | ```js 508 | test.each` 509 | a | b | expected 510 | ${1} | ${1} | ${2} 511 | ${1} | ${2} | ${3} 512 | ${2} | ${1} | ${3} 513 | `('returns $expected when $a is added $b', ({ a, b, expected }) => { 514 | expect(a + b).toBe(expected) 515 | }) 516 | ``` 517 | 518 | Or on `describe` level: 519 | 520 | ```js 521 | describe.each([['mobile'], ['tablet'], ['desktop']])('checkout flow on %s', (viewport) => { 522 | test('displays success page', () => { 523 | // 524 | }) 525 | }) 526 | ``` 527 | 528 | [describe.each() docs](https://jestjs.io/docs/en/api.html#describeeachtablename-fn-timeout), [test.each() docs](https://jestjs.io/docs/en/api.html#testeachtablename-fn-timeout), 529 | 530 | ## Skipping tests 531 | 532 | Do not run these tests: 533 | 534 | ```js 535 | describe.skip('makePoniesPink'... 536 | tests.skip('make each pony pink'... 537 | ``` 538 | 539 | Run only these tests: 540 | 541 | ```js 542 | describe.only('makePoniesPink'... 543 | tests.only('make each pony pink'... 544 | ``` 545 | 546 | ## Testing modules with side effects 547 | 548 | Node.js and Jest will cache modules you `require`. To test modules with side effects you’ll need to reset the module registry between tests: 549 | 550 | ```js 551 | const modulePath = '../module-to-test' 552 | 553 | afterEach(() => { 554 | jest.resetModules() 555 | }) 556 | 557 | test('first test', () => { 558 | // Prepare conditions for the first test 559 | const result = require(modulePath) 560 | expect(result).toMatchSnapshot() 561 | }) 562 | 563 | test('second text', () => { 564 | // Prepare conditions for the second test 565 | const fn = () => require(modulePath) 566 | expect(fn).toThrow() 567 | }) 568 | ``` 569 | -------------------------------------------------------------------------------- /react-quick-reference.md: -------------------------------------------------------------------------------- 1 | # React Quick Reference 2 | 3 | - Components 4 | - [Components](#components) 5 | - [Stateless Components](#stateless-components) 6 | - [Functional Components](#functional-components) 7 | - [Pure Components](#pure-components) 8 | - Properties 9 | - [Props](#properties) 10 | - [States](#states) 11 | - [Children](#children) 12 | - [Nesting](#nesting) 13 | - [Transferring props](#transferring-props) 14 | - [Portals](#portals) 15 | - [Hydration](#hydration) 16 | - [PropTypes](#proptypes) 17 | - [Basic types](#basic-types) 18 | - [Required Types](#required-types) 19 | - [Elements](#elements) 20 | - [Enumerables](#enumerables) 21 | - [Custom validation](#custom-validation) 22 | - [Arrays and Objects](#arrays-and-objects) 23 | - Lifecycle 24 | - [Mounting](#mounting) 25 | - [Updating](#updating) 26 | - [Errors](#errors) 27 | - Hooks 28 | - [State Hook](#state-hook) 29 | - [Effect Hook](#effect-hook) 30 | - [References](#references) 31 | - [DOM Events](#dom-events) 32 | - JSX patterns 33 | - [Style shorthand](#style-shorthand) 34 | - [Conditionals](#conditionals) 35 | - [Lists](#lists) 36 | - [Short-Circuit Evaluation](#short-circuit-evaluation) 37 | - [Fragments and Arrays](#fragments-and-arrays) 38 | 39 | ## Components 40 | 41 | ```javascript 42 | import React from 'react'; 43 | import ReactDOM from 'react-dom'; 44 | 45 | class Hello extends React.Component { 46 | render () { 47 | return ( 48 |
49 | Hello {this.props.name} 50 |
51 | ) 52 | } 53 | } 54 | const el = document.body 55 | ReactDOM.render(, el) 56 | ``` 57 | 58 | ## Stateless Components 59 | 60 | ```javascript 61 | // Stateless React Component 62 | const Headline = () => { 63 | return

React Quick Reference

64 | } 65 | 66 | // Component that receives props 67 | const Greetings = (props) => { 68 | return

You will love it {props.name}.

69 | } 70 | 71 | // Component must only return ONE element (eg. DIV) 72 | const Intro = () => { 73 | return ( 74 |
75 | 76 |

Welcome to the React world!

77 | 78 |
79 | ) 80 | } 81 | 82 | ReactDOM.render( 83 | , 84 | document.getElementById('root') 85 | ); 86 | ``` 87 | 88 | ## Properties 89 | 90 | ```javascript 91 |