使用Redux + Redux Thunk构建您的React应用

Getting started with using Redux and Redux Thunk in your React app

在您的React应用程序中使用Redux和Redux Thunk入门

As your react application gets larger, it gets harder and harder to keep track and maintain your states. This is where Redux can come in to help; it is a state management library that provides you with a central state (called the store), eliminating the need to pass props between components.

随着您的React应用程序变得越来越大,跟踪和维护您的状态变得越来越困难。 这是Redux可以提供帮助的地方; 它是一个状态管理库,可为您提供中央状态(称为存储),而无需在组件之间传递道具。

A quick run through of how Redux works:

快速了解Redux的工作原理:

  1. Create the store

    创建商店
  2. Passing in a reducer as an argument

    将减速器作为参数传递
  3. Reducer update states accordingly based on the type of actions that are dispatched

    根据调度的操作类型,Reducer更新状态相应地

If you don’t already know what Redux is, I’ll recommend you to first read my other article on Redux here.

如果您还不知道Redux是什么,建议您先在此处阅读有关Redux的其他文章。

入门 (Getting Started)

To get started, we first have to install three packages redux, react-redux, and redux-thunk

首先,我们必须安装三个软件包reduxreact-reduxredux-thunk

npm install redux react-redux redux-thunk

Note: redux is simply a JavaScript library that is used with UI frameworks like React and Vue.js while react-redux is a library that we need to use to connect react and redux together. As for redux-thunk, it is a middleware which I’ll explain more in detail in a bit

注意:redux只是一个JavaScript库,可与React和Vue.js等UI框架一起使用,而react-redux是我们需要用来将react和redux连接在一起的库。 至于redux-thunk,它是一个中间件,我将在后面详细解释

跳进去 (Jumping In)

First things first, we’ll need to create the store and the reducer, where the reducer will be passed in as our argument when creating the store.

首先,我们需要创建商店和reducer,在创建商店时,reducer将作为我们的参数传入。

/* store.js */
import { createStore } from 'redux'
const initialState = { x: 1 }
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
x: state.x + 1
}
case 'DECREMENT':
return {
x: state.x + 1
}
case 'RESET':
return {
x: state.x + 1
}
default:
return state;
}
}
const store = createStore(reducer);
export default store;

Here, I’m specifying the type of actions which the reducer can expect. Notice that it will simply return the original state if none of the action type matches ‘INCREMENT’, ‘DECREMENT’ or ‘RESET’ (this is under the default case). It is always good practice to have a default case.

在这里,我指定减速器可以期望的动作类型。 请注意,如果操作类型都不匹配“ INCREMENT”,“ DECREMENT”或“ RESET”(这是默认情况),它将仅返回原始状态。 最好使用默认情况。

Next, we’ll need to wrap our main App component in a component called Provider, which the react-redux library provides. It enables the Redux store to be available in our React App. It takes in a prop called store, which would be the store we just created.

接下来,我们需要将我们的主要App组件包装在一个名为Provider的组件中,react-redux库提供了该组件。 它使Redux商店可以在我们的React App中使用。 它带有一个称为store的道具,这就是我们刚刚创建的store。

import store from './store.js'
<Provider store={store}>
<App/>
</Provider>

Now, without Redux, when creating our React component, we export our components like so:

现在,没有Redux,在创建React组件时,我们将组件导出为:

export default ComponentName;

To make our Redux store available to our components, we will need to call on the connect function provided by the react-redux libary like so:

为了使我们的Redux存储可用于我们的组件,我们将需要像下面这样调用react-redux库提供的connect函数:

export default connect()(ComponentName);

The connect function actually takes in two optional arguments being mapStateToProps and mapDispatchToProps.

connect函数实际上接受两个可选参数,分别是mapStateToProps和mapDispatchToProps。

mapStateToProps (mapStateToProps)

As the name of the function suggests, mapStateToProps enables us to easily map our central state (i.e., our store) to the props of our react component. The result of this means we can access our states through props without needing to pass states between components as we had to do when without Redux.

就像函数名称所暗示的那样,mapStateToProps使我们能够轻松地将中心状态(即我们的商店)映射到我们的react组件的props上。 这样的结果意味着我们可以通过prop访问状态,而无需像没有Redux时那样在组件之间传递状态。

For example, suppose we want to be able to grab our state ‘x’ that we have in our store so that we can access it in our component. Then our mapStateToProps function in our component will look like:

例如,假设我们希望能够获取商店中的状态“ x”,以便可以在组件中访问它。 然后,我们组件中的mapStateToProps函数将如下所示:

const mapStateToProps = state => {
return {
x: state.x
}
}

Which will be passed to the connect function of our component:

这将传递给我们组件的connect函数:

export default connect(mapStateToProps)(ComponentName);

Now, we can access our state value ‘x’ by simply doing props.x

现在,我们只需执行props.x就可以访问状态值“ x”

mapDispatchToProps (mapDispatchToProps)

Similar to mapStateToProps, the mapDispatchToProps function enables us to map functions that dispatches action (I’d like to call these functions dispatchers) to our props. All the function does is returning a plain JavaScript object that contains functions which dispatches actions. The function has a dispatch function as the first argument and an optional ownProps argument. Note that if your mapDispatchToProps function takes two parameters, the function will be re-invoked whenever the connected component receives new props.

与mapStateToProps相似,mapDispatchToProps函数使我们能够将向其道具调度动作(我想将这些函数调度器)分配给道具的函数。 该函数所做的全部工作就是返回一个纯JavaScript对象,该对象包含分派动作的函数。 该函数具有一个调度函数作为第一个参数,以及一个可选的ownProps参数。 请注意,如果您的mapDispatchToProps函数带有两个参数,则只要所连接的组件收到新的道具,该函数就会被重新调用。

For example, with the following code…

例如,使用以下代码…

const mapDispatchToProps = dispatch => {
return {
increment: () => dispatch({ type: 'INCREMENT' }),
decrement: () => dispatch({ type: 'DECREMENT' }),
reset: () => dispatch({ type: 'RESET' })
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ComponentName);

Allows us to do the following…

允许我们执行以下操作…

function App({ x, increment, decrement, reset }) {
return (
<div className="App">
<button onClick={decrement}>-</button>
<span>{x}</span>
<button onClick={increment}>+</button>
<button onClick={reset}>reset</button>
</div>
)
}

Alternatively, we can define mapDispatchToProps with action creators instead. An action creator is a function that generates and returns an action (it doesn’t dispatch the action). If we define mapDispatchToProps like this, connect will automatically call bindActionCreators for you internally which basically wraps our action creators into a dispatch function so that calling them dispatches the action.

另外,我们可以使用动作创建者来定义mapDispatchToProps。 动作创建者是一个生成并返回一个动作的函数(它不会调度该动作)。 如果我们这样定义mapDispatchToProps,则connect会在内部自动为您调用bindActionCreators,这基本上将我们的动作创建者包装到一个调度函数中,以便调用它们来调度动作。

For example, the following implementation of mapDispatchToProps does the exact same thing as our previous implementation.

例如,以下mapDispatchToProps的实现与我们之前的实现完全相同。

const increment: () => ({ type: 'INCREMENT' }),
const decrement: () => ({ type: 'DECREMENT' }),
const reset: () => ({ type: 'RESET' })
const mapDispatchToProps = dispatch => {
return {
increment,
decrement,
reset,
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ComponentName);

Redux Thunk (Redux Thunk)

Oftentimes, when building a web application, you’ll need to call on APIs which means some asynchronous action is going on. Redux Thunk is a middleware that to do these asynchronous actions with Redux. Redux, by itself, does not allow asynchronous actions and this is troublesome if we want to dispatch an action that fetches data from an API for example. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met.

通常,在构建Web应用程序时,您需要调用API,这意味着正在进行一些异步操作。 Redux Thunk是一个中间件,可通过Redux执行这些异步操作。 Redux本身不支持异步操作,如果我们想调度一个例如从API获取数据的操作,这将很麻烦。 重击程序可用于延迟操作的分发,或者仅在满足特定条件时调度。

Quoted from the official documentation:

引用官方文档:

Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

Redux Thunk中间件使您可以编写返回函数而不是操作的操作创建者。 重击程序可用于延迟操作的分发,或者仅在满足特定条件时调度。 内部函数接收存储方法dispatch和getState作为参数。

Image for post

To use redux-thunk, we can modify our code as follows when creating our store:

要使用redux-thunk,我们可以在创建商店时按以下方式修改代码:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(reducers, applyMiddleware(thunk));

Going to our earlier example with our simple increment action creator, with Redux Thunk, it will now have the following structure, which allows us to do asynchronous actions before dispatching our actions.

使用简单的增量动作创建者Redux Thunk,进入我们之前的示例,它现在具有以下结构,这使我们可以在分派动作之前执行异步动作。

const increment: () => async (dispatch, getState) => {
/* some asynchronous action here */
const asyncVal = await someAsyncCall();
dispatch({ type: 'INCREMENT', payload: asyncVal })
},

And that’s basically it for this simple guide to using React with Redux + Redux Thunk! Thanks for reading and hopefully this all makes sense!

基本上,这就是本使用React与Redux + Redux Thunk的简单指南! 感谢您的阅读,希望所有这些都有意义!

翻译自: https://medium.com/swlh/react-with-redux-redux-thunk-b5c2f984d7c2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值