Redux, Thunk, Middleware, Context API, Action, Reducer(state, action), State, Store, dispatch(action), connect()(), mapStateToProps(), ...
redux

Redux, Thunk, Middleware, Context API, Action, Reducer(state, action), State, Store, dispatch(action), connect()(), mapStateToProps(), ...

React Redux State Tree

all of the of Redux data is stored in a single object called the state tree.

We learned that the main goal that Redux is trying to offer is predictable state management.

single state tree all state is stored in one location, we discovered three ways to interact with it:

  1. getting the state
  2. listening for changes to the state
  3. updating the state

Then we combine the three items above and the state tree object itself into one unit which we called the store.

The Store contains the state tree and provides ways to interact with the state tree.

When Store invoked it return an Object that contains the state

store.subscribe()

·????????It is a function.

·????????When called, it is passed a single function.

·????????It returns a function.

first rule! For increasing predictability of state within store

1.??????Only an event can change the state of the store.

  1. The function that returns the new state needs to be a pure function.

When an event takes place in a Redux application, we use a plain JavaScript object to keep track of what the specific event was. This object is called an Action.

an Action is clearly just a plain JavaScript object. What makes this plain JavaScript object special in Redux, is that every Action must have a type property. The purpose of the type property is to let our app (Redux) know exactly what event just took place. This Action tells us that a product was added to the cart. That's incredibly descriptive and quite helpful, isn't it?

If you don't include a type property, Redux will throw an error.

?
?
?        

Action Object is a JavaScript Object that have a type property.

{
? type: "ADD_PRODUCT_TO_CART",
? productId: 17
}        

Action Creators are functions that create and return action objects. For example:

const addItem = item => ({

?type: ADD_ITEM,

?item

});

Action Creators are functions that create/return action objects. For example:

const addItem = item => ({

?type: ADD_ITEM,

?item

});

or in ES5:

var addItem = function addItem(item) {

?return {

???type: ADD_ITEM,

???item: item

?};

};

Can an Action have three or more fields????Yes

There actually isn't any limit to the number of fields an Action may have. However, it's a good idea to keep the amount of payload data as lightweight as possible in each action.

Actions#

An action is a plain JavaScript object that has a type field. You can think of an action as an event that describes something that happened in the application. valid actions

const clearErrors = {
? type: CLEAR_ERRORS
};
const addSeven = {
? type: 'ADD_NUMBER',
? number: 7
};        

Both receivePost functions are action creators, which extrapolate the creation of an action object to a function. clearErrors and addSeven, on the other hand, are action objects with a valid type key and optional payload. removeComments does not include a type key and is an invalid action.

The whole goal of Redux is to increase predictability: Redux is a predictable state container for JavaScript apps.

Second rule! For increasing predictability of state within store

3.??????The function that returns the new state needs to be a pure function.

So far, our rules are:

  1. Only an event can change the state of the store.
  2. The function that returns the new state needs to be a pure function.

A pure function can be a bit theoretical, so we'll take it step by step and explain why a pure function is so powerful and how it helps improve predictability.

What are Pure Functions?

Pure functions are integral to how state in Redux applications is updated.

By definition, pure functions:

  1. Return the same result if the same arguments are passed in
  2. Depend solely on the arguments passed into them
  3. Do not produce side effects, such as API requests, I/O operations and network request

Let’s check out an example of a pure function, square():

// `square()` is a pure function

const square = x => x * x;

square() is a pure function because it outputs the same value every single time, given that the same argument is passed into it. There is no dependence on any other values to produce that result, and we can safely expect just that result to be returned -- no side effects (more on this in a bit!).

On the other hand, let’s check out an example of an impure function, calculateTip():

// `calculateTip()` is an impure function

const tipPercentage = 0.15;

const calculateTip = cost => cost * tipPercentage;

calculateTip() calculates and returns a number value. However, it relies on a variable (tipPercentage) that lives outside the function to produce that value. Since it fails one of the requirements of pure functions, calculateTip() is an impure function. However, we could convert this function to a pure function by passing in the outside variable, tipPercentage, as a second argument to this function!

const calculateTip = (cost, tipPercentage = 0.15) => cost * tipPercentage;

What is true about pure functions? Check all that apply.

·????????Pure functions do not rely on information other than the arguments passed into them to generate an output.

·????????Pure functions do not depend on external state.

Remember that for a function to be pure, it must pass each of the following:

·????????Return the same result if the same arguments are passed in

·????????Depend solely on the arguments passed into them

·????????Do not produce side effects such API or I/O operations

?

The 'console.log' statement is an I/O (input/output) operation, which alters the calling function into an impure function.

const?addAndPrint?=?(a,?b)?=>?{

????const?sum?=?a?+?b;

????console.log(`The?sum?is:?${sum}`);// this make it impure as I/O

????return?sum;

}

?

The whole goal of Redux is to increase predictability: Redux is a predictable state container for JavaScript apps.

Reducer is a pure function that takes state and action and return a new sate.

·????????Pure function

·????????Takes (state & action)

·????????Return new state

Reducers

A Reducer describes how an application's state changes. You’ll often see the Object Spread Operator (...) used inside of a reducer because a reducer must return a new object instead of mutating the old state. If you need a refresher on the spread operator, check out this ES6 lesson. If you want to know why Redux requires immutability, check out the Immutable Data Section of the docs:.

Reducers have the following signature:

(previousState, action) => newState        

Dispatch Modifies, Update the state in store – notify listeners

·????????Modify state

·????????Notify listeners

createStore takes a reducer function name.

Updates to the store can only be triggered by dispatching actions.

The store's subscribe() function helps connect React components to the store. I Think now is connect()

Managing more State

·????????Reducers must be pure

·????????Though each reducer handles a different slice of state, we must combine reducers into a single reducer to pass to the store

·????????createStore() takes only one reducer argument

·????????Reducers are typically named after the slices of state they manage

?

we created a function called createStore() that returns a store object

createStore() must be passed a "reducer" function when invoked

the store object has three methods on it:

.getState() - used to get the current state from the store

.subscribe() - used to provide a listener function the store will call when the state changes – connect React components to the store.

·????????listener function the store will call when the state changes

·????????connect React components to the store.

.dispatch() - used to make changes to the store's state

var action = {
? type: 'ADD_USER',
? user: {name: 'Dan'}
};
?
// Assuming a store object has been created already
store.dispatch(action);        

The dispatch() method sends an object to Redux, known as an action.

Which of the following are true statements about the store? Please select all that apply.

·????????Updates to the store can only be triggered by dispatching actions.

·????????The store's subscribe() function helps connect React components to the store.

functions that create action objects are called Action Creators.

/*?Create?An?Action?Creator

?*

?*?You?need?to?create?an?action?creator?called?'mealCreator'?that?should:

?*???-?Accept?an?id

?*???-?Return?a?Redux?action?with?a?'type'?property?that?has?a?value?of?'CREATE_MEAL'

?*???-?Include?the?id?passed?to?the?action?creator

*/

?

function?mealCreator(id){

????return{

????????type:?'CREATE_MEAL',

????????id,

????}

}

Reducer

/*?Create?A?Reducer

?*

?*?You?need?to?create?a?reducer?called?"appReducer"?that?accepts?two?arguments:

?*?-?First,?an?array?containing?information?about?ice?cream?

?*?-?Second,?an?object?with?a?'DELETE_FLAVOR'?`type`?key

?*?(i.e.,?the?object?contains?information?to?delete?the?flavor?from?the?state)

?*

?*?The?action?your?reducer?will?receive?will?look?like?this:

?*?{?type:?'DELETE_FLAVOR',?flavor:?'Vanilla'?}

?*

?*?And?the?initial?state?will?look?something?like?this?(as?such,?refrain?

?*?from?passing?in?default?values?for?any?parameters!):

?*?[{?flavor:?'Chocolate',?count:?36?},?{?flavor:?'Vanilla',?count:?210?}];

*/

function?appReducer?(state,?action){

????if(action.type==='DELETE_FLAVOR')

??????return?state.filter((iceCream)?=>?iceCream.flavor?!==?action.flavor)

??????

??????return?state

??}

?

?

?

Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the target object.

Syntax

Object.assign(target, ...sources)

Parameters

target

The target object — what to apply the sources’ properties to, which is returned after it is modified.

sources

The source object(s) — objects containing the properties you want to apply.

Return value

The target object.

Why does store.subscribe return unsubscribe function?

·????????it provides a way to stop listening to changes in the store.

·????????Note: Redux is not exclusive to React. It can be used in other projects as well.

// Example One
state.foo = '123';
?
// Example Two
Object.assign(state, { foo: 123 });
?
// Example Three
var newState = Object.assign({}, state, { foo: 123 });        

The object “spread operator” is another way to keep the state immutable:

const newState = { ...state, foo: 123 };
?        

Redux has a state management library that has a store, action, and recducer.

Redux is just a predictable state container.

To createStore for app

const?store?=?Redux.createStore(app)

??You can pass more than one reducer through combineReducers() function

combineReducers is responsible for invoking all the other reducers, passing them the portion of their state that they care about. We're making one root reducer, by composing a bunch of other reducers together.

const?store?=?Redux.createStore(Redux.combineReducers({

????todos,

????goals,

}))

The idea is that you can create a reducer to manage not only each section of your Redux store, but also any nested data as well.

The correct usage of combineReducers() can look like:

import { combineReducers } from 'redux';

import booksReducer from './books_reducer';

import userReducer from './user_reducer';

?

const rootReducer = combineReducers({

???books: booksReducer,

???users: userReducer

});

export default rootReducer;

1) What are the advantages of using Redux? here

·???????A single source of truth for your application state.

·???????A readonly state to ensure that neither the views nor the network callbacks will ever write directly to the state.

·???????And transforming the state through pure functions, called reducers, for predictability and reliability.

Therefore making it a predictable state container for JavaScript application.

1.????Single Source of Truth

2.????State is Read-Only

3.????Changes are made with Pure Functions

Source The what and why of Redux and Leveling Up with React: Redux

For communication between two components that don’t have a parent-child relationship, you can set up your own global event system. … Flux pattern is one of the possible ways to arrange this.

?

?

?

?

In standard Redux App store.dispatch is called the reducer runs.

Middleware Between the dispatching of an action and the reducer running, to intercept ????? the action before the reducer is invoked.

The Redux docs describe middleware as:

…a third-party extension point between dispatching an action, and the moment it reaches the reducer.

With Redux's middleware feature, we can run code between the call to store.dispatch() and reducer().

const store = Redux.createStore( <reducer-function>, <middleware-functions> )

Redux's createStore() method takes the reducer function as its first argument, but then it can take a second argument of the middleware functions to run. Because we set up the Redux store with knowledge of the middleware function, it runs the middleware function between store.dispatch() and the invocation of the reducer.

Applying Middleware

Just as we saw in the previous video, we can implement middleware into a Redux app by passing it in when creating the store. More specifically, we can pass in the applyMiddleware() function as an optional argument into createStore(). Here's applyMiddleware()'s signature:

applyMiddleware(...middlewares)

Note the spread operator on the middlewares parameter. This means that we can pass in as many different middleware as we want! Middleware is called in the order in which they were provided to applyMiddleware().

??Functions Returning Functions ??

Redux middleware leverages a concept called higher-order functions. A higher-order function is a function that either:

  • accepts a function as an argument
  • returns a function

?

Any middleware you supply as the second argument to Redux.createStore() will be run before the reducer is run.

Middleware intercepts a dispatched action before it reaches the reducer.

Redux.applyMiddleware() can accept multiple arguments, Middleware is optional.

Middleware can be considered a third-party extension point between dispatching and having the action reach the reducer.

According to the Redux docs:

Middleware is the suggested way to extend Redux with custom functionality.

Middleware is added to the Redux store using Redux.applyMiddleware(). You can only add middleware when you initially create the store:

const store = Redux.createStore( <reducer-function>, Redux.applyMiddleware(<middleware-functions>) )

?

?

?

?

When to Use Refs ???

There are a few good use cases for refs:

  • Managing focus, text selection, or media playback.
  • Triggering imperative animations.
  • Integrating with third-party DOM libraries.

Avoid using refs for anything that can be done declaratively.

For example, instead of exposing open() and close() methods on a Dialog component, pass an isOpen prop to it.

ref

Refs provide a way to access DOM nodes or React elements created in the render method.

Please note:

React will call the ref callback with the DOM element when the component mounts, and call it with null when it unmounts. Refs are guaranteed to be up-to-date before componentDidMount or componentDidUpdate fires.

componentDidMount()

componentDidMount() is invoked immediately after a component is mounted (inserted into the tree)...If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

forceUpdate()

By default, when your component’s state or props change, your component will re-render. If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate().

Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child. React will still only update the DOM if the markup changes.

Component State vs Redux Store and React + Redux Architecture : Separation of Concerns.

asynchronous requests in Redux.

Redux works right now is:

  • store.dispatch() calls are made
  • if the Redux store was set up with any middleware, those functions are run
  • then the reducer is invoked

?

Promise-Based API

Since the API is Promise-based, we can use Promise.all() to wait until all Promises have resolved before displaying the content to the user.

Promises are asynchronous

the Promise documentation on MDN or check out our JavaScript Promises course.

Optimistic Updates

Instead of waiting for confirmation from the server, just instantly remove the user from the UI when the user clicks “delete”, then, if the server responds back with an error that the user wasn’t actually deleted, you can add the information back in. This way your user gets that instant feedback from the UI, but, under the hood, the request is still asynchronous.

?

??Remember middleware executes in the order it is listed in the applyMiddleware() function.

Thunk

Benefits of Thunks

Out of the box, the Redux store can only support the synchronous flow of data. Middleware like thunk helps support asynchronicity in a Redux application. You can think of thunk as a wrapper for the store’s dispatch() method; rather than returning action objects, we can use thunk action creators to dispatch functions (or even or Promises).

Without thunks, synchronous dispatches are the default. We could still make API calls from React components (e.g., using the componentDidMount() lifecycle method to make these requests) -- but using thunk middleware gives us a cleaner separation of concerns. Components don't need to handle what happens after an asynchronous call, since API logic is moved away from components to action creators. This also lends itself to greater predictability, since action creators will become the source of every change in state. With thunks, we can dispatch an action only when the server request is resolved!

Thunk middleware can then be used to delay an action dispatch, or to dispatch only if a certain condition is met (e.g., a request is resolved). This logic lives inside action creators rather than inside components.

What are the benefits of using thunk middleware?

·???????Asynchronicity

·???????Components don't need to handle what happens after asynchronous calls

?

?

We expect the API request to occur first. TodoAPIUtil.fetchTodos() needs to be resolved before anything else can be done. Once the request is resolved, thunk middleware then invokes the function with dispatch(). Keep in mind: the action is only ever dispatched after the API request is resolved.

?

Summary thunk

If a web application requires interaction with a server, applying middleware such as thunk helps solve the issue of asynchronous data flow. Thunk middleware allows us to write action creators that return functions rather than objects.

By calling our API in an action creator, we make the action creator responsible for fetching the data it needs to create the action. Since we move the data-fetching code to action creators, we build a cleaner separation between our UI logic and our data-fetching logic. As a result, thunks can then be used to delay an action dispatch, or to dispatch only if a certain condition is met (e.g., a request is resolved).

?

?

?

?

?

?

?

?

Getting the Store to Each Component ??? 2

just passing the store down as a prop. It works fine enough in our small app, but what if we had a larger app with more layers to it? Passing the store down ten components deep wouldn't scale very well. One of the main points of having a store is to avoid passing props down through a bunch of components.

we need need to figure out is how to re-render components only if the data they depend on (from the store) changes. Right now, we're solving this by calling getState at the root of our application and then passing the data down. Again, this won't scale well as our app grows.

Context API

It allows us to get data to child component without having to plum it through all of the other components above that component.

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

React's Context API. To begin, we'll use React's createContext() function to return an object with a Provider as well as a Consumer.

const Context = React.createContext();        

Let's now check out how Context.Provider and Context.Consumer make these interactions between components possible!

Context.Provider

The Provider component is used in the upper level of the component tree; that is, the component from which the data to be passed is held. In our case, this was the App component. We passed the name data as the value of Provider's value prop:

class App extends React.Component {

?render() {

?const name = 'Tyler';

?

?return (

???<Context.Provider value={name}>

?????<Parent />

???</Context.Provider>

???);

?}

}

Note that the Provider component simply wraps around the entire component to be rendered!

Context.Consumer

On the receiving end (i.e., a component "under" the Provider in the component hierarchy), we use the Consumer component. In our example, we passed Consumer a function as a child. This function accepts a value and returns some JSX:

function Grandchild ({ name }) {

?return (

???<Context.Consumer>

?????{(name) => (

?????<div>

?????<h1>Grandchild</h1>

?????<h3>Name: {name}</h3>

?????</div>

?????)}

???</Context.Consumer>

?);

}

?

?

Dan Abramov (the creator of Redux!) wrote a post about this very thing. Check it out if to get his take on these concepts: Presentational and Container Components

?

  • A connected component is connected to the Redux store and is responsible for getting data from the store.
  • A presentational component should not access the store. It should receive any information it needs as props and then just render a UI.

?

·????????connect function connects components to the store.

·????????Provider provides the store globally to all subcomponents

·????????Provider is a React component that wraps the application

Provider is really just a React component that we use to wrap the entire application. It takes in the store as a prop, then sets the store context, passing it down to all its subcomponents. All components wrapped by Provider will receive the store context. What differentiates containers from presentational components?

Connect -> is a function connects components to the store.

Connect(data_you_want_to_send props)(components)

const?ConnectedGoals?=?connect((state)?=>?({

????????goals:?state.goals

??????}))(Goals)

?

The react-redux Bindings

Let's take a moment to recap the changes we've made to our app in this Lesson, because we've updated quite a bit!

Previously, we leveraged the standard redux library to build our app. This allowed us to create a Redux store with the createStore() function, giving us an API to listen (subscribe()), get updates (getState()), and make updates (dispatch()) to state. We then created our own Provider component to efficiently pass the store to components that needed it, as well as our own connect() function so that our components can access "slices" of state as props.

We can build a fully-functional React and Redux app without Provider or connect(), but since they greatly simplify how React components interact with the Redux store, the creators of redux have included them in the react-redux package!

Provider

With react-redux, rather than creating and using our own Provider which looks like this:

const Context = React.createContext()??? 
?
class Provider extends React.Component {??? 
??render () {??? 
??return (??? 
????<Context.Provider value={this.props.store}>??? 
??????{this.props.children}??? 
????</Context.Provider>??? 
????);
? }??? 
}
?
ReactDOM.render(
? <Provider store={store}>
? <ConnectedApp />
? </Provider>,
? document.getElementById('app')
);        

...we can simply use the Provider component defined by the react-redux package! This allows us to wrap our entire app with Provider, effectively passing the store to even the most deeply nested components.

ReactDOM.render(
 <ReactRedux.Provider store={store}>
 <ConnectedApp />
 </ReactRedux.Provider>,
 document.getElementById('app')
);        

connect()

Similarly, we can also leverage react-redux's connect() function right out of the box. connect() is a higher-order function that takes in two arguments (as well as a few optional arguments) and returns a function. Check out its signature below:

const buildConnectedComponent = connect(mapStateToProps, mapDispatchToProps);        

What's vital to understand is that buildConnectedComponent is a function. buildConnectedComponent will take a regular (presentational) React component and return a new, "connected" component.

const ConnectedComponent = buildConnectedComponent(MyComponent);        

ConnectedComponent renders MyComponent, passing it the props as defined by mapStateToProps and mapDispatchToPros.

We can avoid having the intermediary buildConnectedComponent variable and just call the functions back-to-back:

const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(MyComponent)        

Notice the double set of parentheses!

connect() connects which two items?

·????????Store

·????????Component

Using connect(), we can conveniently access the store context set by Provider. We pass in parts of the state as well as action-dispatches to the components as props.

Remember the signature of the connect() function: connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

Assume that MyComponent is a simple React component. How can MyComponent access state?

mapStateToProps is a function that lets connect() know how to map state into the component’s list of props.

Summary

React often leverages Redux for more predictable state management via the react-redux bindings. These bindings give us an API that simplifies the most common interactions between React and Redux.

Provider makes it possible for Redux to pass data from the store to any React components that need it. It uses React’s context feature to make this work.

connect() connects a React component to the Redux store. The mapStateToProps() function allows us to specify which state from the store you want passed to your React component, while the mapDispatchToProps() function allows us to bind dispatch to action creators before they ever hit the component.

Create React App

npm install -g create-react-app
create-react-app goals-todos
yarn start
?
?        

According to the Redux documentation, here are the principles of state normalization:

  • Each type of data gets its own "table" in the state.
  • Each "data table" should store the individual items in an object, with the IDs of the items as keys and the items themselves as the values.
  • Any references to individual items should be done by storing the item's ID.
  • Arrays of IDs should be used to indicate ordering.

accessing the store from an action creator is considered an anti-pattern.

Which of the following are best practices for making API requests in React apps? Select all that apply.

·????????The componentDidMount() lifecycle method

Which of the following are best practices for making API requests in React/Redux apps? Select all that apply.

·????????From asynchronous action creators

That’s right! Did you know that there are other side effect management libraries besides redux-thunk that help you make async requests like redux-sagas, and axios calls? If you want to learn more about the differences between these libraries, check out this article.

Remember how normal Action Creators return actions - simple Javascript objects that then go to all of our reducers? Making an API request is an asynchronous action, so we cannot just send a plain Javascript object to our reducers. Redux middleware can gain access to an action when it's on its way to the reducers. We'll be using the redux-thunk middleware in this example.

If the Redux Thunk middleware is enabled (which is done via the applyMiddleware() function), then any time your action creator returns a function instead of a Javascript object, it will go to the redux-thunk middleware.

Dan Abramov describes what happens next:

“The middleware will call that function with dispatch method itself as the first argument...The action will only reach the reducers once the API request is completed. It will also “swallow” such actions so don't worry about your reducers receiving weird function arguments. Your reducers will only receive plain object actions—either emitted directly, or emitted by the functions as we just described.”

Initializing State

There are 2 ways to initialize the state inside the store:

  • You can pass the initial state (or a part of the initial state) as preloadedState to the createStore function.

For example:

const store = createStore (
? rootReducer,
? { tweets: {} }
);        

  • You can include a default state parameter as the first argument inside a particular reducer function.

For example:

function tweets (state = {}, action) {
}        

To see how these approaches interact, check out the Initializing State section of the documentation.

?

to install the react-redux package à yarn add react-redux redux
?        

Redux applications have a single store. We have to pass the Root Reducer to our createStore() function in order for the store to know what pieces of state it should have. The point of creating a store is to allow components to be able to access it without having to pass the data down through multiple components.

The Provider component (which comes from the react-redux package) makes it possible for all components to access the store via the connect() function.

?
?        

Errors

TypeError: __WEBPACK_IMPORTED_MODULE_0_react___default.a.createContext is not a function

?

Solution

Need to yarn upgrade react react-dom or npm update react react-dom. See https://stackoverflow.com/questions/54521723/react-default-createcontext-is-not-a-function-when-using-react-redux

Middleware

Our last bit of setup involves setting up the app's Middleware functions. Just like in the previous Todos application, we're going to create a logger middleware that will help us view the actions and state of the store as we interact with our application. Also, since the handleInitialData() action creator in src/actions/shared.js returns a function, we'll need to install the react-thunk package:

yarn add redux-thunk

In the next video, we’ll hook up our redux-thunk middleware, so our thunk action creators actually work. We’ll also put in logger middleware to make debugging easier. Do you remember how to build custom middleware?

All middleware follows this currying pattern:

const logger = (store) => (next) => (action) => {
 // ...
}        

Use the Babel Repl if you want to see this code in ES5.

The variable logger is assigned to a function that takes the store as its argument. That function returns another function, which is passed next (which is the next middleware in line or the dispatch function). That other function return another function which is passed an action. Once inside that third function, we have access to store, next, and action.

It’s important to note that the value of the next parameter will be determined by the applyMiddleware function. Why? All middleware will be called in the order it is listed in that function. In our case, the next will be dispatch because logger is the last middleware listed in that function.

That's right! The middleware is called in the order it is listed in this function. The thunk action creators we're using to load initial date, save tweets, and toggle tweets are functions. So if they go to the logger middleware before going to the thunk middleware (which takes the functions and executes them, thereby obtaining actions to pass to the reducers), we're going to be logging function, not the actual actions.

?

?

Using the connect() function upgrades a component to a container. Containers can read state from the store and dispatch actions. Read more about our ability to customize our container’s relationship with the store in the react-redux API documentation.

To make a container, we need to make use the connect() function. Remember that the signature of the connect function looks like this:

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

Take a look at the react-redux documentation if you need a refresher.

These details about mapStateToProps and mapDispatchToProps are crucial:

mapStateToProps - If this argument is specified, the new component will subscribe to Redux store updates. This means that any time the store is updated, mapStateToProps will be called. The results of mapStateToProps must be a plain object, which will be merged into the component’s props. If you don't want to subscribe to store updates, pass null or undefined in place of mapStateToProps.

mapDispatchToProps - If an object is passed, each function inside it is assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into a dispatch call so they may be invoked directly, will be merged into the component’s props. If a function is passed, it will be given dispatch as the first parameter. It’s up to you to return an object that somehow uses dispatch to bind action creators in your own way. (Tip: you may use the bindActionCreators() helper from Redux.)

Remember that the signature of the mapStateToProps function is:

mapStateToProps(state, [ownProps])

  • state is the state inside the store
  • ownProps are the properties that have been passed to this component from a parent component

The Perils of Using a Common Redux Anti-Patterns

mapStateToProps is called whenever the store is updated

When will the mapStateToProps function be called? Select all that apply.

  • Anytime the store is updated
  • Whenever the component receives new props.

?

yarn add react-router-dom

Quick React Router Review

BrowserRouter listens for changes in the URL and makes sure that the correct screen shows up when the URL changes.

<BrowserRouter>

??<App />

</BrowserRouter>

will allow us to

  • use the other components browser-router-dom comes with inside of our app
  • listen to the URL so that whenever the url changes, the routing components will be notified of the change

Link Component

<Link to="/about">About</Link>        

Users navigate through React apps with the help of the Link Component.

The Link component talks to the BrowserRouter and tells it to update the URL. By passing a to property to the Link component, you tell your app which path to route to.

What if you wanted to pass state to the new route? Instead of passing a string to Links to prop, you can pass it an object like this:

<Link to={{
 pathname: '/courses',
 search: '?sort=name',
 hash: '#the-hash',
 state: { fromDashboard: true }
}}>
 Courses
</Link>        

use --> https://www.npmjs.com/package/render-fragment

npm i --save render-fragment

react-redux-loading

these React/Redux sample projects

?

?

?

?

?

?

Easy Redux Tutorial: Adding Redux to a Simple React App Youtube

Components get their data through this.props

Connect () ()

Connect Component to redux using connect () () function from react-redux.

Connect is Higher-order function when calls it returns connected component.

We export connected counter not only a counter component.

mapStateToProps (state)

Only what you need is that you send through connect function through mapStateToProps

mapStateToProps (state) this function takes entire redux state and return object with keys are prop names and values are props values

createStore (reducer)

from redux createStore() function ?const store = connectStore();

to provide store to app?we use provider component to do that

provider component comes from react-redux so we import { Provider } from ‘react-redux’

and wrap root of app with that provider

provider takes one props called store that we created.

reducer (state, action)

initial state and how state changes

createStore(reducer) expect a reducer function to tell redux initial state of the store ???????

reducer(state=initialState,action) you can separate initial state in a function as a default argument to get that sate

it’s important to always return the state unchanged if this reducer doesn’t handle the action that’s been given so don’t forget default case that return state ???????????

dispatch(action)

to get action that in reducer we can’t just call the action directly. store has a function on it is called dispatch.

dispatch action is only way to change store

store.dispatch({type:’INCREMENT’}) pass in action object à this is a plain JS object that have a type property

when call reducer first time it gets initial state then second time dispatch action

?

?

react-bootstrap not working

https://stackoverflow.com/questions/47354472/react-bootstrap-not-styling-my-react-components

1)?????npm i --save bootstrap

2)?????import 'bootstrap/dist/css/bootstrap.css';

When pass props in Link react-router

https://stackoverflow.com/questions/30115324/pass-props-in-link-react-router

// your route setup

<Route path="/category/:catId" component={Category} / >

?

// your link creation

const newTo = {

?pathname: "/category/595212758daa6810cbba4104",

?param1: "Par1"

};

// link to the "location"

// see (https://reacttraining.com/react-router/web/api/location)

<Link to={newTo}> </Link>

?

// In your Category Component, you can access the data like this

this.props.match.params.catId // this is 595212758daa6810cbba4104

this.props.location.param1 // this is Par1

Would You Rather Code Review

If you want to take your skills further in React and Redux, you can visit the official React and Redux documentation where you can find a lot of really interesting articles. Example-

Also, with React 16.8, React Hooks is available in the stable release. Reference- React Hooks announcement

You can find some suggestions for a good README here- Suggestions for a Good README.

For that, you check out the official redux style guide.

Here are some helpful resources that can help us write better code-

?

We can use mapDispatchToProps to get a function in props that can dispatch a specific action.

  • This helps us separate concerns in a component and write more maintainable code.

Example-

export default connect(mapStateToProps, { handleInitialData })(App);        

Then, we can write this line as-

this.props.handleInitialData();        

References-

·?Redux thunk has been properly used to handle async actions.

Recall that Redux is a predictable state container for JavaScript applications.

Redux is agnostic to any particular view library or framework, the same principles of Redux will apply to applications built with React Native as well.

1.??????Actions

2.??????Reducers

3.??????Provider Create Store

4.??????Connect

When connect Component to redux using connect()(ComponetName), you can use this.props.dispatch in this component.

Don’t mutate the state mean that don’t delete element in state obj but make a copy of it

https://stackoverflow.com/questions/59897667/delete-key-from-state-redux-reducer

You should just be able to call delete state[action.id]. Although as you're in a reducer function, you should take a copy of the state first, delete from that, then return the copied version.

case: 'HANDLE_DECREASE_CHANGE':
? const next = {...state}
? delete next[action.id]
? return next        

?

要查看或添加评论,请登录

社区洞察