johnny-dreamguns
10/7/2019 - 10:23 PM

Building applications with React and Redux

Building applications with React and Redux

NPM- Packages are listed by major.minor.patch Tilde ~ indicates the most recent patch version in the specified minor version Caret ^ indicates the most recent minor version in the specified major version

Babel- The .babelrc file controls which version of ES to transpile the bundle to The babel polyfill adds functionality such as Promise, Array.from and Object.assign

@babel/preset-env is the recommended way to include the latest features

ESLint- The .eslintrc file configures ESLint and overrides some of the rules 0 = Off 1 = Warning 2 = Error

Npm scripts options: "prestart" - script to run before start "start" - script to run on start

Npm scripts, commonly used packages: babel-node - run JS file like Node but with babel support lint - esw command will link the listed files or directories npm-run-all allows you to run multiple npm scripts

When to use container components: State Refs Lifecycle methods Child functions

Container Components: Little to no markup Pass data and actions down Know about Redux Dispatch redux actions Often stateful Generated by react-redux

Presentation Components: Nearly all markup Receive data and actions via props Don't know about Redux Functional Components Invoke callbacks on props Written by hand

You don't always have Container components at the top of the hierarchy

Redux principles: One immutable store Actions trigger changes Reducers update state with pure functions, takes current state and updates it

Redux enforces a unidirectional flow of data

Store and change logic are separate One store Singleton store with hierarchical reducers No dispatcher Container components utilize connect State is immutable

Action Creators: Plain objects containing a description of the event Must have a type property Also contains a payload of json encoded data Created using convenience functions

Store can: dispatch an action subscribe a listener getState: return its current state replace a reducer (for hot reloading)

Immutability: To change state return a new object (instead of changing the existing one)

To return a new copy of state use Object.assign from babel polyfill: Object.assign({}, state, { role: 'admin })

Benefits of immutability: Clarity: obvious which reducer changed state Performance: don't have to check if each property has changed Time travel debugging

Enforce immutability: Trust redux-immutable-state-invariant (displays an error if you mutate state) Immutable.js

Reducers: To change the store you dispatch an action that is handled by a reducer A function that takes in state and an action and returns new state

Forbidden in reducers: Mutate arguments ( Perform side effects (API Calls) Call non-pure functions Reducers should only rely on the params passed in No use of Date now or Math random

Redux should only have one store and multiple reducers

All reducers are called on each dispatch The switch in each reducer decides if the reducer is going to act Each reducer should return the untouched state by default Each reducer is only passed its slice of the state All the reducers together form the complete picture of what is in the store

Reducer composition: Write independent small reducer functions that are each responsible for a specific slice of the state An action could be handled by all, some or no reducers, no one to one mapping

Memoize with 'Reselect': Caching for function calls

Bind methods to this in the constructor: this.myMethod = this.myMethod.bind(this);

Redux flow: Dispatch action Actions picked up by all reducers MapStateToProps maps new state to component Component is re-rendered

mapStateToProps adds state to a component mapDispatchToProps adds actions to a component bindActionCreators is shorthand for adding a group of action creators

Container Structure: Constructor Methods Render PropTypes Map Store to Component

actionTypes.js can be used to list all the actions so they aren't hard coded

A thunk is a function that is returned by a function, redux-thunk is used so that action creators can make async calls

A container component that connects to redux should ideally not also have JSX inside, separate into child components

An action creator that deals with async data should ideally be suffixed with 'success' or 'failure'

To keep things neat destructure objects before you pass them as an attribute: const { courses } = this.props;

Useful files: actions/actionTypes for definining action constants selectors/selectors for functions that convert data into different formats reducers/initialState for object containing initialState data

Thunk functions can access the state using the getState function

Context allows access to things like router within a component

mapStateToProps: The state param gives you access to all of the redux state, you can use this to return whatever is needed to a component The ownProps param allows you to access the components props

componentWillReceiveProps is a lifecycle method that runs whenever props change

then and catch can be used with thunks in order to show and hide different elements depending on the state of the async calls

toastr can be used to show an info flash message or error message

State tracking a number 'ajaxCallsInProgress' is useful, show a spinner when calls are being made

React test utils- React testing library built by Facebook

React test utils- shallowRender

  • Renders a single component without rendering any children
  • Ensures your component is a unit and isn't dependent on child components
  • Returns an object that is what we would expect to see in the real DOM so no DOM is required
  • Fast and simple

renderIntoDocument

  • Renders a component and its children
  • Dom is required

Get rendered dom components- findRenderedDOMComponentWithTag scryRenderedDOMComponentsWithTag

Simulate- This allows you to simulate clicks, keypresses etc and then assert on the outcome

Enzyme is a great add on to React test utils, providing Cheerio, a JQuery like syntax

Places to run tests: In Browser (Run using Karma) Headless Browser (Phantom JS) In memory DOM (Run tests via Node)

Enzyme refers to 'renderIntoDocument' as 'mount'

Shallow render easily allows checking HTML rendered depending on different props passed to a Dumb component, can be tested in memory rather than using a real browser

Derived data should be stored in files called selectors, there's a library called reselect that can help with this

Mounted render allows checking of functionality when actions occur, when a button is clicked then check the right changes occur

Unit testing action creators is as simple as checking that the right object is returned

Testing reducers is a matter of passing in data and checking that the right changes are made

To test a thunk we have to mock the store and http calls that are made

  • To mock the store use redux-mock-store
  • To mock the HTTP calls use nock (Node mocks)

The mock store keeps track of what actions were created during the test, can

Production build: configureStore.prod and configureStore.dev may be worth considering to only use those parts of middleware that are needed

eslint-disable disables any unwanted lint errors

production and dev versions of the webpack config

Use buildHTML script to copy modified index.html file to dist