by Matthew Choi

由Matthew Choi

使用React构建Tesla的电池范围计算器(第2部分:Redux版本) (Building Tesla’s Battery Range Calculator with React (Part 2: Redux version))

This tutorial is the second part of building Tesla’s battery range calculator with React.

本教程是使用React构建特斯拉电池范围计算器的第二部分。

In part 1, after constructing the project through create-react-app, we implemented each component by subdividing the UI. We managed the state and event using local state and props, and completed the entire app.

在第1部分中,通过create-react-app构建项目后,我们通过细分UI来实现每个组件。 我们使用本地状态和道具管理状态和事件,并完成了整个应用程序。

If you haven’t read it yet, be sure to check out Part 1, which focuses on React, here:

如果您还没有阅读它,请确保在这里阅读有关React的第1部分:

Building Tesla’s Battery Range Calculator with React (Part 1)In this series of articles, I will walk you through the process of building Tesla’s battery range calculator with React…medium.freecodecamp.com

使用React构建Tesla的电池范围计算器(第1部分) 在本系列文章中,我将引导您完成使用React构建Tesla的电池范围计算器的过程 。medium.freecodecamp.com

In this installment, we’ll introduce Redux, a state management solution, to see how we can transform our application into an application that manages the state of the app with Redux.

在本期中,我们将介绍状态管理解决方案Redux,以了解如何将应用程序转换为使用Redux管理应用程序状态的应用程序。

This is the final image of our application in part 2:

这是第2部分中应用程序的最终图像:

? Check out the part 2 live demo.

? 请查看第2部分的在线演示。

Before we taking a look into what Redux is, let’s see why we need to use Redux to solve problems.

在研究什么是Redux之前,让我们看看为什么需要使用Redux来解决问题。

1.我们要解决什么问题? (1. What problem do we solve?)

Redux is getting becoming the de facto way to build React apps. But should Redux be used in all React apps? At the very least, not all apps will need an ambitious state management solution from the beginning.

Redux正在成为构建React应用程序的实际方法。 但是Redux是否应该在所有React应用程序中使用? 至少从一开始,并不是所有的应用程序都需要雄心勃勃的状态管理解决方案。

Today’s front-end development trends are component-based. Components can have data state and UI state, and the state that they need to manage becomes more and more complicated as your app grows.

当今的前端开发趋势是基于组件的 。 组件可以具有数据状态和UI状态,并且随着应用程序的增长,它们需要管理的状态变得越来越复杂。

State management solutions have emerged to solve the following problems, and Redux is becoming popular as a standard among other solutions.

为了解决以下问题,出现了状态管理解决方案,并且Redux在其他解决方案中已成为标准。

  • components share state

    组件共享状态
  • state should be accessible from anywhere

    状态应该可以从任何地方访问
  • components need to mutate the state

    组件需要改变状态
  • components need to mutate the state of other components

    组件需要改变其他组件的状态

Redux is a state management library, which is a tool that allows you to store the state of our app somewhere, mutate the state, and receive the updated state.

Redux是一个状态管理库 ,它是一个工具,可让您在某个地方存储我们的应用程序状态,更改状态并接收更新后的状态。

In other words, with Redux, we have one place where we can refer the state, change the state, and get the updated state.

换句话说,在Redux中,我们有一个地方可以引用状态,更改状态并获取更新的状态。

Redux was written with React in mind, but it is also framework-agnostic and even can be used with Angular or jQuery applications.

Redux是在考虑到React的情况下编写的,但它与框架无关 ,甚至可以与Angular或jQuery应用程序一起使用。

I recommend you read Dan Abramov’s You Might Not Need Redux before choosing Redux.

建议您在选择Redux之前先阅读Dan Abramov的“ 您可能不需要 Redux”。

2. Redux中的数据流 (2. Data flow in Redux)

As you saw in the part 1, in React, the data is passed through the component using props. This is called unidirectional data flow that flows from parent to child.

如您在第1部分中所见,在React中,数据通过props通过组件传递。 这称为从父级流到子级的单向数据流

Due to these characteristics, communication between components other than parent-child relationship is not clear.

由于这些特性,除父子关系之外的组件之间的通信尚不清楚。

React does not recommend direct component-to-component communication as shown above. There is a suggested way for this in React, but you have to implement it yourself.

如上所述,React不建议直接进行组件间通信。 在React中有一种建议的方法,但是您必须自己实现。

According to React docs:

根据React docs

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.
要在没有父子关系的两个组件之间进行通信,可以设置自己的全局事件系统。 …助焊剂模式是解决此问题的一种可能方法。

This is where Redux comes in handy.

这是Redux派上用场的地方。

Redux provides a solution for managing all application state in a single place called a store.

Redux提供了一种解决方案,用于在称为store的单个位置管理所有应用程序状态。

The component then dispatches the state change to the store instead of passing it directly to the other components

然后,该组件将状态更改dispatches到存储,而不是将其直接传递给其他组件

The components that need to be aware of state changes can subscribe to the store.

需要了解状态变化的组件可以subscribe商店。

Redux is, in a word, a state container that represents and manages the state of an app as a single object from a JavaScript-based application.

总之,Redux是一个状态容器 ,它作为基于JavaScript的应用程序中的单个对象来表示和管理应用程序的状态。

3. Redux核心概念 (3. Redux Core Concept)

Redux itself is very simple. The state of the app we created in the last article can be represented as a generic object like this:

Redux本身非常简单。 我们在上一篇文章中创建的应用程序的状态可以表示为通用对象,如下所示:

This object is the same as the model without setters.

该对象与不带setter的模型相同。

To change this state in Redux, you must dispatch an action.

要在Redux中更改此状态,您必须调度action

Actions are plain objects describing what happened in the app, and serve as the sole way to describe an intention to mutate the data. It’s one of the fundamental design choices of Redux.

动作是描述应用程序中发生的事情的简单对象,并且是描述意图改变数据的唯一方法。 这是Redux的基本设计选择之一。

Here are some examples to be implemented in our app soon.

以下是一些即将在我们的应用中实现的示例。

Forcing all of these state changes into action will give us a clear understanding of what’s going on in your app. When something happens, we can see why it happened.

强制执行所有这些状态更改将使我们对您的应用程序中发生的事情有清晰的了解。 当某些事情发生时,我们可以看到为什么发生。

Now we need a function called reducer to bind these states and actions together. Reducer is nothing more than a function that takes a state and an action as arguments and returns a new state.

现在我们需要一个称为reducer的函数来将这些状态和动作绑定在一起。 Reducer只是一个将状态和操作作为参数并返回新状态的函数。

In a word:

一句话:

(state, action) => state

(状态,动作)=>状态

Actions only describe that something happened and don’t specify how the application’s state changes in response. This is the job of reducers.

动作仅描述发生了某些事情,没有指定应用程序的状态如何响应 。 这是减速器的工作。

Here is one example of a reducer to implement in our app:

这是在我们的应用程序中实现的reducer的一个示例:

4. Redux的三项原则 (4. Redux Three Principles)

I’ve mentioned Flux a few times. Flux is a pattern of state management, not a downloadable tool like Redux. Redux, on the other hand, is a practical implementation of the Flux pattern and has three main principles.

我已经提到过几次Flux 。 Flux是状态管理的一种模式 ,不是Redux这样的可下载工具。 另一方面,Redux是Flux模式实际实现,它具有三个主要原理。

4.1真理的单一来源 (4.1 Single source of truth)

The state of the entire application is stored in an object tree within a single store.

整个应用程序的状态存储在单个存储中的对象树中。

Since all states exist in one place, this is called a single source of truth.

由于所有状态都存在于一个地方,因此这被称为single source of truth

This one-store approach of Redux is one of the primary differences between it and Flux’s multiple store approach.

Redux的这种one-store方法是它与Flux的多商店方法之间的主要区别之一。

What are the advantages of a single state tree? This makes it easier to debug applications or perform internal inspections and to easily implement some features that were previously difficult to implement (for example, undo / redo).

单一状态树的优点是什么? 这使得调试应用程序或执行内部检查以及轻松实现以前难以实现的某些功能(例如,撤消/重做)变得更加容易。

4.2状态为只读 (4.2 State is read-only)

The only way to change the state is to emit an action that describes what happened.

更改状态的唯一方法是发出描述所发生情况的操作。

In other words, the application does not directly change the state, but instead expresses the intention to transform the state by passing the action.

换句话说,应用程序不直接更改状态,而是表达通过传递动作来转换状态的意图。

In fact, if you look at the Redux API, you can see that it consists of just four methods:

实际上,如果您查看Redux API,则可以看到它仅包含四种方法:

store.dispatch(action)store.subscribe(listener)store.getState()replaceReducer(nextReducer)

As you can see, there is no setState() method. Therefore, passing an action is the only channel that can mutate the state of the application.

如您所见,没有setState()方法。 因此, 传递动作是唯一可以改变应用程序状态的通道。

4.3使用纯函数进行更改 (4.3 Changes are made with pure functions)

You write reducers as pure functions to specify the concrete way the state tree is transformed by action.

您将化简器编写为纯函数,以指定通过动作转换状态树的具体方式。

Reducers are pure functions that take a previous state and action and return a new state. Keep in mind that you must return a new state object instead of changing the old state.

约简器是纯函数,它们具有先前的状态和操作并返回新的状态。 请记住,您必须返回一个新的状态对象,而不是更改旧的状态。

“Given the same arguments, it should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Just a calculation.” — Redux Docs

“给出相同的参数,它应该计算下一个状态并返回它。 没什么好奇怪的 没有副作用。 没有API调用。 没有突变。 只是计算而已。” — Redux文档

The pure function has the following characteristics:

纯函数具有以下特征:

  • It does not make outside network or database calls.

    它不会进行外部网络或数据库调用。
  • Its return value depends solely on the values of its parameters.

    它的返回值仅取决于其参数的值。
  • Its arguments should be considered “immutable”, meaning they should not be changed.

    其参数应被认为是“不变的”,这意味着它们不应被更改。
  • Calling a pure function with the same set of arguments will always return the same value.

    用相同的参数集调用纯函数将始终返回相同的值。

5.将应用程序分为容器和组件 (5. Divide The App Into Containers and Components)

Now, let’s re-build our Tesla calculator app that we made in Part 1 as a Redux version.

现在,让我们重新构建在第1部分中作为Redux版本构建的Tesla计算器应用程序。

First, let’s look at the overall component UI layout of the app that will be implemented in this article.

首先,让我们看一下将在本文中实现的应用程序的整体组件UI布局

Placing React and Redux logic inside a single component can be messy, so it is recommended that you create a Presentational component for presentation purposes only, and a Container component, an upper wrapper component that handles Redux and dispatches actions.

将React和Redux逻辑放在单个组件中可能会很混乱,因此建议您创建一个Presentational组件,仅用于演示目的,而Container组件是一个处理Redux并分派动作的上层包装器组件。

The role of the parent Container component is to provide state values to presentational components, to manage events, and to communicate with Redux on behalf of presentational components.

父容器组件的作用是为表示组件提供状态值,以管理事件,并代表表示组件与Redux通信。

6.列出每个组件的状态和操作 (6. List State and Actions For Each Component)

Refer to the entire component layout to create a list of states and actions for each component:

请参考整个组件布局,以为每个组件创建状态和动作的列表:

TeslaCar Container :	state : wheels	action : N/A
TeslaStats Container :	state : carstats(array)	action : N/A	TeslaSpeedCounter Container : 	state : config.speed	action : SPEED_UP, SPEED_DOWN
TeslaTempCounter Container : 	state : config.temperature	action : TEMPERATURE_UP, TEMPERATURE_DOWN	TeslaClimate Container : 	state : config.climate	action : CHANGE_CLIMATE
TeslaWheel Container : 	state : config.wheel	action : CHANGE_WHEEL

7.设置第1部分项目代码库 (7. Set up part 1 project code base)

If you want to go directly to part 2 without looking at part 1, you need to build the codebase first by cloning the part 1 code.

如果您想不看第1部分而直接进入第2部分,则需要首先通过克隆第1部分代码来构建代码库。

After the npm start, let’s make sure the application works.

npm start之后 ,让我们确保该应用程序正常运行。

  • git clone https://github.com/gyver98/part1-react-tesla-battery-range-calculator-tutorial

    git clone https://github.com/gyver98/part1-react-tesla-battery-range-calculator-tutorial

  • npm install

    npm安装

  • npm start

    npm开始

8.为每个动作创建动作创建者 (8. Create Action Creators For Each Action)

Now that you’ve created an action list, it’s time to create action creators.

现在,您已经创建了动作列表,是时候创建action creators

An action creator is a function that literally creates an action object. In Redux, action creators simply return an action object and pass the argument value if necessary.

动作创建者是从字面上创建动作对象的函数。 在Redux中,动作创建者只需返回一个动作对象,并在必要时传递参数值。

changeWheel action creator sample :

changeWheel动作创建者示例:

const changeWheel = (value) => {  return {    type: 'CHANGE_WHEEL',    value  }}

These action creators are passed to the dispatch function as the result value, and the dispatch is executed.

这些动作创建者作为结果值传递到调度函数,并执行调度。

dispatch(changeWheel(size))

The dispatch function can be accessed directly from the store as store.dispatch(), but in most cases it will be accessed using a helper like react-redux’s connect(). We’ll look at connect later.

可以从商店以store.dispatch()的形式直接访问调度功能,但是在大多数情况下,将使用诸如react-redux的connect()类的助手来访问该调度功能。 我们稍后再看连接

8.1创建Action.js (8.1 Create Action.js)

Create an index file in the src/actions directory and define action creators as follows:

在src / actions目录中创建一个索引文件,并按如下所示定义动作创建者:

src/actions/index.js

src / actions / index.js

import { counterDefaultVal } from '../constants/counterDefaultVal';
export const speedUp = (value) => {  return {    type: 'SPEED_UP',    value,    step: counterDefaultVal.speed.step,    maxValue: counterDefaultVal.speed.max  }}
export const speedDown = (value) => {  return {    type: 'SPEED_DOWN',    value,    step: counterDefaultVal.speed.step,    minValue: counterDefaultVal.speed.min  }}
export const temperatureUp = (value) => {  return {    type: 'TEMPERATURE_UP',    value,    step: counterDefaultVal.temperature.step,    maxValue: counterDefaultVal.temperature.max  }}
export const temperatureDown = (value) => {  return {    type: 'TEMPERATURE_DOWN',    value,    step: counterDefaultVal.temperature.step,    minValue: counterDefaultVal.temperature.min  }}
export const changeClimate = () => {  return {    type: 'CHANGE_CLIMATE'  }}
export const changeWheel = (value) => {  return {    type: 'CHANGE_WHEEL',    value  }}
export const updateStats = () => {  return {    type: 'UPDATE_STATS'  }}
  • Check out index.js

    查看index.js

Because we need default values based on the action creator, we define this constant value in constants/counterDefaultVal under src directory and import it.

因为我们需要基于动作创建者的默认值 ,所以我们在src目录下的constants / counterDefaultVal中定义此常量值并将其导入。

src/constants/counterDefaultVal.js

src /常量/counterDefaultVal.js

export const counterDefaultVal = {  speed: {    title: "Speed",    unit: "mph",    step: 5,    min: 45,    max: 70  },  temperature: {    title: "Outside Temperature",    unit: "°",    step: 10,    min: -10,    max: 40  }}
  • Check out counterDefaultVal.js

    退房counterDefaultVal.js

9.为每个动作创建减速器 (9. Create Reducers For Each Action)

Reducers are functions that receive state and action objects from a Redux store and return a new state to be stored back into Redux.

减速器是从Redux存储接收状态和动作对象并返回新状态以存储回Redux的函数。

It’s important not to directly modify the given state here. Reducers must be pure functions and must return a new state.

重要的是不要在此处直接修改给定状态。 减速器必须是纯函数,并且必须返回新状态

  • Reducer functions are called from the Container that will be created when a user action occurs.

    从发生用户操作时将创建的容器调用Reducer函数。

  • When the Reducer returns a state, Redux passes the new state to each component, and React renders each component again.

    当Reducer返回状态时, Redux将新状态传递给每个组件,然后React再次渲染每个组件

9.1不可变的数据结构 (9.1 Immutable Data Structures)

  • JavaScript primitive data type(number, string, boolean, undefined, and null) => immutable

    JavaScript基本数据类型(数字,字符串,布尔值,未定义和null)=&g t; 不可变的

  • Object, array and function => mutable

    对象,数组和函数=&g t; 可变

Changes to the data structure are known to be buggy. Since our store consists of state objects and arrays, we need to implement a strategy to keep the state immutable.

已知对数据结构的更改存在错误。 由于我们的商店由状态对象和数组组成,因此我们需要实施一种策略来保持状态不变

There are three ways to change the state here:

这里有三种更改状态的方法:

ES5

ES5

// Example Onestate.foo = '123';
// Example TwoObject.assign(state, { foo: 123 });
// Example Threevar newState = Object.assign({}, state, { foo: 123 });

In the example above, the first and second mutate the state object. The second example mutates because Object.assign() merges all its arguments into the first argument.

在上面的示例中,第一个和第二个突变状态对象。 第二个示例发生了变化,因为Object.assign()将其所有参数合并到第一个参数中。

The third example doesn’t mutate the state. It merges the contents of state and { foo: 123 } into a new empty object which is the first argument.

第三个例子没有改变状态 。 它将state和{foo:123}的内容合并到一个新的空对象中 ,该对象是第一个参数。

The spread operator introduced in ES6 provides a simpler way to keep the state immutable.

ES6中引入的散布运算符提供了一种更简单的方法来保持状态不变。

ES6 (ES2015)

ES6(ES2015)

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

For more information about the spread operator, see here.

有关点差运算符的更多信息,请参见此处 。

9.2为ChangeClimate创建减速器 (9.2 Create a Reducer for ChangeClimate)

First, we will create ChangeClimate through test-driven development method.

首先,我们将通过测试驱动的开发方法来创建ChangeClimate。

In Part1, our app was generated through create-react-app, so we basically use jest as test runner.

在第1部分中,我们的应用程序是通过create-react-app生成的 ,因此我们基本上使用jest作为测试运行器。

The jest looks for a test file using one of the following naming conventions:

开玩笑地使用以下命名约定之一查找测试文件:

Files with .js suffix in __tests__ foldersFiles with .test.js suffixFiles with .spec.js suffix

Create teslaRangeApp.spec.js in src/reducers and create a test case.

在src / reducers中创建teslaRangeApp.spec.js并创建一个测试案例。

describe('test reducer', () => {  it('should handle initial stat', () => {    expect(      appReducer(undefined, {})    ).toEqual(initialState)  })})

After create the test, run the npm test command. You should be able to see the following test failure message. This is because we have not written the appReducer yet.

创建测试后,运行npm test命令。 您应该能够看到以下测试失败消息。 这是因为我们尚未编写appReducer

To make the first test successful, we need to create teslaRangeApp.js in the same reducers directory and write initial state and reducer functions.

为了使第一个测试成功,我们需要在相同的reducers目录中创建teslaRangeApp.js并编写初始状态和reducer函数。

src/reducers/teslaRangeApp.js

src / reducers / teslaRangeApp.js

const initialState = {  carstats:[    {miles:246, model:"60"},    {miles:250, model:"60D"},    {miles:297, model:"75"},    {miles:306, model:"75D"},    {miles:336, model:"90D"},    {miles:376, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: true,    wheels: 19  }}
function appReducer(state = initialState, action) {  switch (action.type) {        default:      return state   }}
export default appReducer;

Next, import teslaRangeApp.js from teslaRangeApp.spec.js and set initialState.

接下来,从teslaRangeApp.spec.js导入teslaRangeApp.js并设置initialState。

src/reducers/teslaRangeApp.spec.js

src / reducers / teslaRangeApp.spec.js

import appReducer from './teslaRangeApp';
const initialState =  {  carstats:[    {miles:246, model:"60"},    {miles:250, model:"60D"},    {miles:297, model:"75"},    {miles:306, model:"75D"},    {miles:336, model:"90D"},    {miles:376, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: true,    wheels: 19  }}
describe('test reducer', () => {  it('should handle initial stat', () => {    expect(      appReducer(undefined, {})    ).toEqual(initialState)  })})

Run npm test again and the test will succeed.

再次运行npm test,测试将成功。

In the current test case, the action type is {}, so the initialState is returned.

在当前测试用例中,操作类型为{},因此返回initialState

Now let’s test the CHANGE_CLIMATE action.

现在让我们测试CHANGE_CLIMATE动作。

Add the following climateChangeState and CHANGE_CLIMATE test cases to teslaRangeApp.spec.js.

将以下ClimateChangeState和CHANGE_CLIMATE测试用例添加到teslaRangeApp.spec.js。

const climateChangeState = {  carstats:[    {miles:267, model:"60"},    {miles:273, model:"60D"},    {miles:323, model:"75"},    {miles:334, model:"75D"},    {miles:366, model:"90D"},    {miles:409, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: false,    wheels: 19  }}
it('should handle CHANGE_CLIMATE', () => {    expect(      appReducer(initialState,{        type: 'CHANGE_CLIMATE'      })    ).toEqual(climateChangeState)  })

Then add the CHANGE_CLIMATE case, updateStats, and calculateStats functions to teslaRangeApp.js. Then import the BatteryService.js that was used in part 1.

然后将CHANGE_CLIMATE情况, updateStatscalculateStats函数添加到teslaRangeApp.js。 然后导入第1部分中使用的BatteryService.js

import { getModelData } from '../services/BatteryService';
function updateStats(state, newState) {  return {    ...state,    config:newState.config,    carstats:calculateStats(newState)  }  }
function calculateStats(state) {  const models = ['60', '60D', '75', '75D', '90D', 'P100D'];  const dataModels = getModelData();  return models.map(model => {    const { speed, temperature, climate, wheels } = state.config;    const miles = dataModels[model][wheels][climate ? 'on' : 'off'].speed[speed][temperature];    return {      model,      miles    };  });}
function appReducer(state = initialState, action) {  switch (action.type) {    case 'CHANGE_CLIMATE': {      const newState = {        ...state,        config: {          climate: !state.config.climate,          speed: state.config.speed,          temperature: state.config.temperature,          wheels: state.config.wheels        }      };      return updateStats(state, newState);    }    default:      return state  }}

If you check the test results, you can see that the two test cases are successful.

如果检查测试结果,则可以看到两个测试用例均成功。

What we have implemented so far is that the changes in the state that occur when the user turns the air conditioner on and off in the application through the test runner only from the viewpoint of Action and Reducer without Redux Store or View.

到目前为止,我们已经实现的是,仅从没有Redux Store或View 的Action and Reducer角度来看,当用户通过测试运行程序在应用程序中打开和关闭空调时,状态发生了变化。

  • Check out teslaRangeApp.js as we’ve written it so far

    到目前为止我们已经写了teslaRangeApp.js

  • Check out teslaRangeApp.spec.js

    查看teslaRangeApp.spec.js

9.3为他人创建Reducer (9.3 Create Reducer for others)

If you create the rest of the test cases by referring to the above method, you finally define the teslaRangeApp.js file in which the reducers of all the apps are defined and the teslaRangeApp.spec.js to test them.

如果您通过参考上述方法创建其余测试用例,则最终定义teslaRangeApp.js文件(其中定义了所有应用程序的简化程序)以及teslaRangeApp.spec.js进行测试。

The final code can be found at:

最终代码可以在以下位置找到:

  • teslaRangeApp.js

    teslaRangeApp.js

  • teslaRangeApp.spec.js

    teslaRangeApp.spec.js

After completing the code and testing, a total of seven test cases must succeed.

完成代码和测试后,总共必须成功完成七个测试用例。

10.观点:聪明而笨拙的组成部分 (10. The views: smart and dumb components)

As mentioned in 5. Divide The App Into in Containers and Components, we will create Presentational components (dumb components) for presentation purposes and a Container components (smart components) which are wrapper component responsible for Actions while communicating with Redux.

5.在容器和组件中划分应用程序所述 ,我们将创建用于表示目的的Presentational组件 (哑组件)和一个Container组件 (智能组件),这些组件是与Redux通信时负责Action的包装器组件。

Smart components are responsible for the actions. If a dumb component underneath them needs to trigger an action, the smart component will pass a function through props, and the dumb component can then treat that as a callback.

智能组件负责这些动作 。 如果它们下面的一个哑组件需要触发一个动作,则智能组件将通过prop传递一个函数,然后哑组件可以将其视为回调

We already have dumb components for presentation purposes in part 1, and will reuse them.

在第1部分中,我们已经有用于演示目的的哑组件,并将重复使用它们。

Here we create container components as upper wrapper around each dumb components.

在这里,我们创建容器组件作为每个哑组件的上部包装

10.1视图层绑定 (10.1 The view layer binding)

Redux needs some help to connect the store to the view. It needs something to bind the two together. This is called the view layer binding. In an app that uses react, this is react-redux.

Redux需要一些帮助来将商店连接到视图。 它需要一些东西将两者绑定在一起。 这称为视图层绑定 。 在使用react的应用程序中,这是react-redux

Technically, a container component is just a React component that uses store.subscribe() to read a part of the Redux state tree and supply props to a presentational component it renders.

从技术上讲,容器组件只是一个React组件,它使用store.subscribe()来读取Redux状态树的一部分并将道具提供给它呈现的呈现组件。

Hence, we can manually create container components, but this is not recommended for Redux official docs. This is because react-redux performs many performance optimizations that are difficult to perform manually.

因此,我们可以手动创建容器组件,但是Redux官方文档不建议这样做。 这是因为react-redux会执行许多难以手动执行的性能优化

For this reason, instead of writing the container component by hand, we write it using the connect() function provided by react-redux.

因此,我们不用手工编写容器组件,而是使用react-redux提供的connect()函数编写它。

Let’s install the necessary packages first.

让我们先安装必要的软件包。

  • npm install –save redux

    npm install –保存redux

  • npm install –save react-redux

    npm install –保存react-redux

10.2 TeslarCar集装箱 (10.2 TeslarCar Container)

To use connect(), you need to define a special function called mapStateToProps. This function tells you how to convert the current Redux store state to props to be passed to the presentation component.

要使用connect() ,您需要定义一个名为mapStateToProps的特殊函数。 此功能告诉您如何将当前Redux商店状态转换为要传递给演示组件的道具

The TeslarCar container takes the wheelsize stored in the current store and passes it to props so that it can be rendered by the TeslarCar component. This props will be updated every time the state is updated.

TeslarCar容器将存储在当前商店中的车轮尺寸传递给道具,以便可以由TeslarCar组件进行渲染。 每次更新状态时,此道具都会更新。

After defining the mapStateToProps function, we defined the connect() function as shown below.

定义mapStateToProps函数之后,我们定义了connect()函数,如下所示。

const TeslaCarContainer = connect(mapStateToProps, null)(TeslaCar)

connect() accepts mapDispatchToProps as the second argument, which takes the dispatch method of the store as its first argument. In the TeslaCar component, we do not need an action, so we have to pass null.

connect()接受mapDispatchToProps作为第二个参数,它将商店的调度方法作为第一个参数。 在TeslaCar组件中,我们不需要操作,因此我们必须传递null。

Another parenthesis in connect()() may look weird. This form actually means two function calls, the first connect() returns another function, and the second function needs you to pass a React component. In this case it’s our TeslaCar component. This pattern is called currying or partial application and is a form of functional programming.

connect()()中的另一个括号可能看起来很奇怪。 这种形式实际上意味着两个函数调用,第一个connect()返回另一个函数第二个函数需要您传递React组件 。 在这种情况下,这是我们的TeslaCar组件。 这种模式称为currying部分应用程序 ,是功能编程的一种形式。

Create src/containers/TeslaCarContainer.js and write the code.

创建src / containers / TeslaCarContainer.js并编写代码。

Check out TeslaCarContainer.js

查看TeslaCarContainer.js

10.3 TeslaStats容器 (10.3 TeslaStats Container)

As with the TeslaCar container, define only the mapStatToProps function and pass it to connect() in TeslaStats container.

与TeslaCar容器一样,仅定义mapStatToProps函数并将其传递给TeslaStats容器中的connect()。

Create src/containers/TeslaStatsContainer.js and write the code.

创建src / containers / TeslaStatsContainer.js并编写代码。

Check out TeslaStatsContainer.js

查看TeslaStatsContainer.js

10.4 TeslaSpeedCounter容器 (10.4 TeslaSpeedCounter Container)

The TeslaSpeedCounter container defines an additional mapDispatchToProps function to handle the user actions that occur in the TeslaSpeedCounter component.

TeslaSpeedCounter容器定义了一个附加的mapDispatchToProps函数,以处理TeslaSpeedCounter组件中发生的用户操作。

Create src/containers/TeslaSpeedCounterContainer.js and write the code.

创建src / containers / TeslaSpeedCounterContainer.js并编写代码。

Check out TeslaSpeedCounterContainer.js

查看TeslaSpeedCounterContainer.js

10.5 TeslaTempCounter容器 (10.5 TeslaTempCounter Container)

The TeslaTempCounter container is almost identical to the TeslaSpeedCounter except for the state and action creators being passed.

除了传递状态和动作创建者之外, TeslaTempCounter容器TeslaSpeedCounter几乎相同。

Create src/containers/TeslaTempCounterContainer.js and write the code.

创建src / containers / TeslaTempCounterContainer.js并编写代码。

Check out TeslaTempCounterContainer.js

查看TeslaTempCounterContainer.js

10.6 TeslaClimateContainer (10.6 TeslaClimateContainer)

Create src/containers/TeslaClimateContainer.js and write the code.

创建src / containers / TeslaClimateContainer.js并编写代码。

Check out TeslaClimateContainer

看看TeslaClimateContainer

10.7 TeslaWheelsContainer (10.7 TeslaWheelsContainer)

Create src/containers/TeslaWheelsContainer.js and write the code.

创建src / containers / TeslaWheelsContainer.js并编写代码。

Check out TeslaWheelsContainer.js

查看TeslaWheelsContainer.js

We have created the container components corresponding to the presentation components generated in part 1 through connect() of react-redux.

我们已经通过react-redux的connect()创建了与第1部分中生成的表示组件相对应的容器组件。

11.提供者 (11. Provider)

Let’s put together all the things we’ve done so far and make our apps work. So far we have defined action objects and created action creators that create action objects. And when an action occurs, we have created reducers that actually treat and return a new state. We then created a container component that connects each of the presentation components to the Redux store.

让我们将到目前为止所做的所有事情汇总起来,使我们的应用程序正常运行。 到目前为止,我们已经定义了动作对象并创建了创建动作对象的动作创建者 。 当动作发生时,我们创建了实际上可以处理并返回新状态的减速器 。 然后,我们创建了一个容器组件 ,用于将每个演示组件连接到Redux存储。

Now every container component needs a way to access the store, which is what the Provider does. The Provider component wraps the entire application and allows subcomponents to communicate with the store via connect().

现在,每个容器组件都需要一种访问商店的方法,这就是Provider所做的。 Provider组件包装了整个应用程序,并允许子组件通过connect()与商店进行通信

The top-level component of our app, App.js, looks like this:

我们应用程序的顶级组件App.js如下所示:

Check out App.js

查看App.js

12.他们如何一起工作 (12. How they all work together)

Finally, all the puzzle pieces were completed. Now let’s look at the following animation as an example of when all the puzzle pieces are tied together and the user triggers the speed up event.

最终,所有拼图块都完成了。 现在,让我们看下面的动画,作为所有拼图块捆绑在一起并且用户触发加速事件的示例。

Now run npm start and it will be compiled normally and the application will be started.

现在运行npm start ,它将正常编译并启动应用程序。

But there are still a few things to do.

但是仍然有一些事情要做。

  • First, copy all the contents of /containers/TeslaBattery.css that you created in part 1 and add them to App.css.

    首先,复制您在第1部分中创建的/containers/TeslaBattery.css的所有内容,并将它们添加到App.css中

Check out App.css

签出App.css

  • Next, open /components/TeslaCounter/TeslaCounter.js and modify the onClick event handler as follows: This is because part 2 no longer handles event handling in TeslaBattery.js.

    接下来,打开/components/TeslaCounter/TeslaCounter.js并按如下所示修改onClick事件处理程序:这是因为第2部分不再处理TeslaBattery.js中的事件处理。

onClick={(e) => props.increment(e, props.initValues.title)}-->onClick={(e) => {  e.preventDefault();  props.increment(props.currentValue)}}
onClick={(e) => props.decrement(e, props.initValues.title)}-->onClick={(e) => {  e.preventDefault();  props.decrement(props.currentValue)}}
  • Next, let’s not use props repeatedly by using ES6 Object destructuring.

    接下来,我们不要通过使用ES6 Object Destructuring重复使用props。
const TeslaCounter = (props) => (  <p className="tesla-counter__title">{props.initValues.title}&lt;/p>  ...
-->const TeslaCounter = ({ initValues, currentValue, increment, decrement }) => (  <p className="tesla-counter__title">{initValues.title}</p>  ...

Check out TeslaCounter.js

查看TeslaCounter.js

Finally, our Redux version of Tesla Battery Range Calculator app is complete!

终于,我们的Redux版本的Tesla Battery Range Calculator应用程序完成了!

13.另外一件事:Redux Dev Tools (13. One more thing: Redux Dev Tools)

The Redux Dev Tool makes it much easier to view Redux state tracking and take advantage of cool features like time travel debugging.

Redux Dev Tool使查看Redux状态跟踪变得更加容易,并利用了诸如时程调试之类的出色功能。

We’ll install it on Chrome here.

我们将在此处将其安装在Chrome上。

  • Chrome extension install

    Chrome扩展程序安装

  • Add for Redux store

    为Redux商店添加

Open the App.js file and modify the createStore part as follows:

打开App.js文件,并按如下所示修改createStore部分:

const store = createStore(appReducer);-->const store = createStore(appReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
  • Check on browser

    在浏览器上检查

在继续下一部分之前: (Before you go on to the next part:)

  • Check out the final project code

    查看最终的项目代码

  • Check out the live demo

    查看现场演示

其他资源: (Additional resources:)

  • Redux docs

    Redux文档

  • A cartoon intro to Redux

    Redux的卡通简介

  • Leveling Up with React: Redux

    使用React升级:Redux

  • Getting Started with Redux

    Redux入门

翻译自: https://www.freecodecamp.org/news/building-teslas-battery-range-calculator-with-react-part-2-redux-version-2ffe29018eec/

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Ionic-wechat项目边开发边学(三):自定义样式,指令,服务

    上一篇文章主要介绍了一个ionic项目的标准目录结构&#xff0c;header标签的使用&#xff0c;以及页面之间的切换。这篇文章实现的功能有: 消息数据的获取, 消息列表的展示, 消息标为已读/未读, 主要涉及的到的知识点有: ion-list的使用ion-popup的使用通过sass自定义样式loca…...

    2024/4/20 16:27:38
  2. SimscapeMultibody 物理建模

    Simscape Multibody 物理建模 文章目录Simscape Multibody 物理建模简介一、创建模型二、创建机械连接块类型说明连接块图设置Solid block特性设置**Rigid Transform**块生成子系统添加旋转部件设置重力设置单摆起始位置配置求解器组装模型运行模型分析模型测量单摆运动添加以下…...

    2024/4/20 16:27:36
  3. karma jasmine_使用Jasmine和Karma测试AngularJS(第2部分)

    karma jasmine我们的目标 ( Our Goal ) In this tutorial we will be creating and testing the user profile page for the employee directory we started building in Part 1 of this tutorial. The user profile page will show the details of each employee. Due to the …...

    2024/4/20 16:27:35
  4. 10 种最常见的 Javascript 错误 — 总结于 1000+ 个项目,并阐述如何避免

    引用原文地址&#xff1a;https://rollbar.com/blog/top-10-javascript-errors/ 更多文章参见&#xff1a; https://github.com/elevenbeans/elevenbeans.github.io 为了回馈我们的开发者社区&#xff0c;我们查看了数千个项目的数据库&#xff0c;发现了 JavaScript 中频度最高…...

    2024/4/20 16:27:34
  5. 如何使用ui-router中的ui-sref将参数传递给控制器

    本文翻译自&#xff1a;How to pass parameters using ui-sref in ui-router to controllerI need to pass and recieve two parameters to the state I want to transit to using ui-sref of ui-router. 我需要使用ui-sref的ui- ui-sref将两个参数传递给我想转移到的状态。 S…...

    2024/4/19 19:28:55
  6. 双眼皮啥时候能化妆

    ...

    2024/4/18 23:05:52
  7. 双眼皮眼睛两边提机不一样

    ...

    2024/4/13 11:48:02
  8. 开内眼角一个月了可以做双眼皮吗

    ...

    2024/4/12 21:25:08
  9. 阿克苏医院割成都哪里割双眼皮靠谱不

    ...

    2024/4/16 20:32:19
  10. 苏州双眼皮哪家医院

    ...

    2024/4/12 18:07:33
  11. 割上海做双眼皮犀利d6美来8

    ...

    2024/4/13 10:24:00
  12. 整容双眼皮?心上海美来8

    ...

    2024/4/20 0:08:58
  13. angular中使用openlayer画运动轨迹从初始化开始

    angular中使用openlayer画运动轨迹从初始化开始 初始化地图 mapBasicLayerSource new OSM({warpX: true });//加载街道地图 // 初始化地图 initMap() {const view new View({center: [],zoom: this.zoomLevel,projection: EPSG:4326,minZoom: this.MinZoom,maxZoom: this.M…...

    2024/4/16 20:53:19
  14. 九院双眼皮犀利d6上海美来8

    ...

    2024/4/13 3:09:35
  15. 双眼皮价钱犀利d6上海美来8

    ...

    2024/4/8 12:02:55
  16. angularjs ng-show ng-hidden

    简述一下需求&#xff1a;需要根据绑定的model数据的值来判断某个区域是显示还是隐藏&#xff1f; 解决办法&#xff1a;使用angularjs的ng-show 标签完成 首先想到的时候在页面初始化加载model时使用ng-show“check()”,去js中调用该check方法来判断model的某一属性是否为空…...

    2024/4/20 2:34:11
  17. AngularJS入门(用ng-hide指令实现元素显示和隐藏)

    为什么80%的码农都做不了架构师&#xff1f;>>> 控制html元素显示和隐藏有n种方法&#xff1a;html的hidden、css的display、jquery的hide()和show()、bootstrap的.hide。今天的重点不是显示和隐藏&#xff0c;而是监听某个布尔变量值&#xff0c;自动改变元素显示…...

    2024/4/12 18:07:13
  18. angularjs 的模型无法绑定到隐藏域(input hidden)

    描述一下问题&#xff1a; 在操作表单中的隐藏域的时候发现angularjs的模型无法绑定&#xff0c;比如&#xff1a; <input type"hidden" name"someData" ng-model"data" /> 在网上找到了解决办法&#xff0c;特意记录&#xff1b;原文&…...

    2024/4/12 18:07:28
  19. Angular笔记--引用第三方JavaScript 类库

    项目&#xff1a;使用NG-ALAIN&#xff0c;是基于 Angular 和 NG-ZORRO&#xff08;Ant Design 的 Angular 版本&#xff09; 基础组件库的中后台前端解决方案 引用第三方JavaScript 类库&#xff0c;以引入 driver.js----操作指引 为例 1 安装依赖包 yarn add driver.js 安装完…...

    2024/4/12 18:07:13
  20. angularjs -- 密码输入框的内容可见与隐藏(ng-class)

    在注册或登录密码输入框右侧会出现一个眼睛的小图标&#xff0c;点击时密码可见或隐藏&#xff0c;这个功能用angularjs的ng-class的属性&#xff0c;很容易就实现了&#xff0c;如下&#xff1a; 1. html代码&#xff1a; <div class"item item-input"><…...

    2024/4/18 11:45:21

最新文章

  1. 如何查看微信公众号发布文章的主图,如何看微信文章的主图,怎么才能拿到主图

    如何查看&#xff0c;微信公众号发布文章的主图&#xff0c;如何看微信文章的主图 起因是这样的&#xff0c;当我看到一篇文章的时候&#xff0c;他的主图很漂亮&#xff0c;但是&#xff0c;正文里没有&#xff0c;而我又想看到&#xff0c;并且使用这张图片&#xff0c;该怎么…...

    2024/4/20 21:26:52
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 蓝桥杯第十五届抱佛脚(十)贪心算法

    蓝桥杯第十五届抱佛脚&#xff08;十&#xff09;贪心算法 贪心算法基本概念 贪心算法是一种在算法设计中常用的方法&#xff0c;它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是最好或最优的算法。 贪…...

    2024/4/19 0:49:59
  4. C++ 【原型模式】

    简单介绍 原型模式是一种创建型设计模式 | 它使你能够复制已有对象&#xff0c;客户端不需要知道要复制的对象是哪个类的实例&#xff0c;只需通过原型工厂获取该对象的副本。 以后需要更改具体的类或添加新的原型类&#xff0c;客户端代码无需改变&#xff0c;只需修改原型工…...

    2024/4/19 0:29:52
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/19 14:24:02
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/19 18:20:22
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/19 11:57:31
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/19 11:57:31
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/19 11:57:52
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/19 11:57:53
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/19 11:58:14
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/19 11:58:20
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/20 7:40:48
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/19 11:58:39
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/19 11:58:51
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/20 3:12:02
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/19 11:59:15
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/19 11:59:23
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/19 11:59:44
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/19 11:59:48
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/19 12:00:06
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/20 21:12:02
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/19 12:00:25
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/19 12:00:40
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57