Redux初学者指南

by Safeer Hayat

通过更安全的哈亚特

Understanding Redux as a beginner can be quite confusing. Redux has an abundance of new terms and concepts which are often pretty unintuitive. This guide presents a very simplified example of a Redux implementation. I will define each of the steps and terms in a way that makes sense to a complete beginner.

将Redux理解为初学者可能会造成很大的困惑。 Redux有很多新术语和新概念,这些新术语和新概念通常很不直观。 本指南提供了Redux实现的非常简化的示例。 我将以适合初学者的方式定义每个步骤和术语。

This is intended to be a guide to demystify Redux elements. It does not contain the most technically accurate definitions. It does not have the best ever practices. It does have definitions that will help develop an understanding for someone with no prior knowledge of these concepts. There is a simple implementation as to not confuse with unnecessary details.

这旨在作为使Redux元素神秘化的指南。 它不包含技术上最准确的定义。 它没有最佳实践。 它确实具有一些定义,这些定义将有助于对以前不了解这些概念的人有所了解。 有一个简单的实现方式,可以与不必要的细节混淆。

The example we will run through in this guide will be a simple todo app. The app allows a user to add or remove todo items and see them displayed on the page.

我们将在本指南中运行的示例是一个简单的待办应用程序。 该应用程序允许用户添加或删除待办事项,并在页面上显示它们。

I will run through step by step each element of Redux, explaining what that element is and how to implement it with code examples. Scroll to the bottom to see the full code example which will show how it all fits together as a complete React app.

我将逐步介绍Redux的每个元素,说明该元素是什么以及如何通过代码示例实现它。 滚动到底部以查看完整的代码示例,该示例将显示如何将它们全部组合成一个完整的React应用程序。

步骤摘要 (Steps Summary)

  1. Write the reducer function

    编写减速器功能
  2. Instantiate the store in the root component

    在根组件中实例化商店
  3. Wrap the components with the <Provider> component, passing in the store as a prop

    用<Provider>组件包装组件,将其作为道具传入商店
  4. Write the component

    编写组件
  5. Define the actions

    定义动作
  6. Define the dispatch, attach these to where the dispatches will be triggered (ie event listeners etc)

    定义调度,将它们附加到将触发调度的位置(即事件侦听器等)
  7. Define the mapStateToProps function

    定义mapStateToProps函数
  8. Export the connect function, passing in mapStateToProps and null as the 2 arguments and passing the component name in the second pair of brackets

    导出connect函数,传入mapStateToProps和null作为2个参数,并在第二对括号中传递组件名称

脚步 (Steps)

1.编写减速器功能 (1. Write the reducer function)

The reducer function is a function which tells the store how to respond to actions. The function returns the new and updated state whenever an action is dispatched. State is immutable (can’t be changed) so the reducer always returns a new state. The reducer usually uses the spread operator to insert the current state into a new object/array and appending to it. Common practice is to use a switch/case statement and check the type property of the action passed in. Then write the code that updates the state for each case.

减速器功能是告诉商店如何响应动作的功能。 每当分派操作时,该函数都会返回新状态和更新状态。 状态是不可变的(无法更改),因此减速器始终返回新状态。 精简器通常使用散布运算符将当前状态插入到新的对象/数组中并追加到该对象/数组中。 通常的做法是使用switch / case语句并检查传入的操作的type属性。然后编写更新每种情况的状态的代码。

We write our reducer function first because we will need to pass this when we instantiate our store. To understand what’s happening though requires some knowledge of actions and dispatch. We will cover this further on in this guide.

我们首先编写reducer函数,因为在实例化商店时我们将需要传递它。 要了解正在发生的事情,需要对操作和调度有一定的了解。 我们将在本指南中对此进行进一步介绍。

For now know that our todo app will need to interact with the store in 2 ways: to add a new todo item to the state and to remove a todo item from the state. Therefore we write our function so that it responds to 2 cases of the action type. It uses the action value to either add or remove a todo item from the state.

现在,我们的待办事项应用程序将需要通过两种方式与商店交互:将新的待办事项添加到州,并从州中删除待办事项。 因此,我们编写函数以使其能够响应2种情况的动作类型。 它使用操作值在状态中添加或删除待办事项。

The reducer is passed 2 parameters: state (this is the entire state currently in the store, and we give it a default value if state does not exist yet) and the action. We return the state in the default case.

reducer传递了2个参数:状态(这是商店中当前的整个状态,如果状态不存在,则为它提供默认值)和操作。 我们以默认情况返回状态。

2.实例化根组件中的存储 (2. Instantiate the store in the root component)

The store is the thing which actually contains the state in it. It’s a bit magical and you don’t really need to know the ins and outs of it. All you need to know is that you don’t access it directly like you would a normal React state. You access it and make changes to it using reducers, actions and dispatch.

商店实际上就是其中包含状态的事物。 这有点神奇,您实际上不需要了解它的来龙去脉。 您需要知道的是,您不会像正常的React状态那样直接访问它。 您可以访问它并使用化简器,操作和调度对其进行更改。

The other important thing to know about the store is that it contains some useful and important methods. The main method is the dispatch function. It also contains a getState method (for viewing the state) and subscribe method (runs a callback every time an action is dispatched).

关于商店的另一件重要的事情是它包含一些有用且重要的方法。 主要方法是调度功能。 它还包含getState方法(用于查看状态)和subscription方法(每次分派操作时运行回调)。

The store is typically instantiated at the root of your app (e.g. App.js). It is stored as a variable and has the reducer passed in as a parameter. The store is then passed in as a prop to the Provider component.

该商店通常在应用程序的根目录(例如App.js)上实例化。 它存储为变量,并将减速器作为参数传递。 然后将商店作为道具传递给提供程序组件。

We instantiate our store object passing in the reducer we just created.

我们实例化传入刚刚创建的化简器的商店对象。

3.用<Provider>组件包装组件,将其作为道具传入商店 (3. Wrap the components with the <Provider> component, passing in the store as a prop)

The Provider is a component created to make it easier to pass the store to all your components. The Provider component wraps around all your components (e.g. render your components as children of Provider). You pass the store in as a prop to the Provider only. This means you don’t need to pass in the store as a prop to every component as each component gets it from the Provider. However, this doesn’t mean the components have access to the state yet. You still need to use the mapStateToProps (we will cover this later) to have the state accessible in your component.

提供程序是一个创建的组件,它使将商店传递给所有组件变得更加容易。 Provider组件包装了所有组件(例如,将组件渲染为Provider的子代)。 您只能将商店作为道具传递给提供者。 这意味着您不需要将存储作为每个组件的道具传递,因为每个组件都可以从提供者那里获取。 但是,这并不意味着组件还可以访问状态。 您仍然需要使用mapStateToProps(我们将在以后进行介绍)以使状态可在组件中访问。

We wrap the Todo component we are going to make with our Provider component. We pass in the store we created in the previous step.

我们使用Provider组件包装要制作的Todo组件。 我们传入在上一步中创建的商店。

4.编写组件 (4. Write the component)

Next, we begin to write the Todo component which will render the todo items and interact with the Redux store.

接下来,我们开始编写Todo组件,该组件将渲染待办事项并与Redux商店进行交互。

The component is a stateful component containing one state element to keep track of what the user has typed into the input. We have a function called handleChange. This function updates the state every time the user types anything into the input. So far this is all we will write. We need to understand more about Redux before we can write the logic. The logic will add new todos to the state and retrieve current ones from the state to render on the page.

该组件是一个有状态的组件,其中包含一个状态元素,以跟踪用户在输入中键入了什么。 我们有一个称为handleChange的函数。 每当用户在输入中输入任何内容时,此功能都会更新状态。 到目前为止,这就是我们要写的全部内容。 在编写逻辑之前,我们需要了解有关Redux的更多信息。 逻辑将向状态添加新的待办事项,并从状态中检索当前待办事项以呈现在页面上。

5.定义动作 (5. Define the actions)

An action is a simple object containing a property called ‘type’. This object is passed into the dispatch function. It is used to tell the store what event has just occurred (by reading the actions type property). It also tells what update it should make to the state in response (through the reducer function). The action can also contain other properties for any other data you want to pass into the reducer. Data can only be passed through here so any data needed will need to be passed in here.

动作是一个简单的对象,其中包含一个称为“类型”的属性。 该对象传递到调度函数中。 它用于告诉商店刚刚发生了什么事件(通过读取action type属性)。 它还告诉响应状态(通过reducer函数)应对状态进行哪些更新。 该操作还可以包含要传递给化简器的任何其他数据的其他属性。 数据只能在此处传递,因此所需的任何数据都需要在此处传递。

We will use action creators to define our actions. Action creators are a function which returns the action object. Its purpose is to make the action more portable and testable. It doesn’t change the behavior of how anything works. It’s another method of writing and passing the action. It also allows you to pass in parameters if you want to send data with the action which we will be doing. So we require to use action creators here.

我们将使用动作创建者来定义我们的动作。 动作创建者是一个返回动作对象的函数。 其目的是使操作更具可移植性和可测试性。 它不会改变任何事物的行为。 这是编写和传递动作的另一种方法。 如果您想通过我们将要执行的操作发送数据,它还允许您传递参数。 因此,我们需要在此处使用动作创建者。

If you remember our reducer responded to 2 action types — “ADD_TODO” and “REMOVE_TODO”. We will define those actions with our action creators. In our add_todo action will return “ADD_TODO” as the type and the todo item we want to add to the store as the value (we need the store to add this todo item to the state so it gets passed in here). In the remove_todo we return “REMOVE_TODO” as the type and the index of the todo item in the store as the value. We’ll need this to remove it from the list of todos.

如果您还记得,我们的减速器对两种动作类型进行了响应-“ ADD_TODO”和“ REMOVE_TODO”。 我们将与动作创建者一起定义这些动作。 在我们的add_todo操作中,将返回“ ADD_TODO”作为类型,并返回要添加到存储中的待办事项作为值(我们需要商店将此待办事项添加到状态,以便它在此处传递)。 在remove_todo中,我们返回“ REMOVE_TODO”作为类型,并返回商店中待办事项的索引作为值。 我们需要此功能将其从待办事项列表中删除。

If you return to our reducer function definition hopefully it now makes more sense. By reading the action.type the reducer knows whether it needs to add a todo to the state or remove one from it. It has the todo item passed in the add_todo. It appends to the current state using the spread operator. In the remove_todo it uses the spread operator to create a new array appending the current state sliced twice, once with all the elements before the one to remove and second with all the elements after the one to remove, thus creating our new state object with the todo item removed.

如果您希望返回我们的化简函数定义,那么现在更有意义了。 通过读取action.type,reducer知道它是否需要向状态添加待办事项或从状态中删除一个待办事项。 它在add_todo中传递了待办事项。 使用扩展运算符将其附加到当前状态。 在remove_todo中,它使用spread运算符创建一个新的数组,该数组将切成两次的当前状态附加到切片中,一次删除所有元素,然后删除所有元素,从而创建一个新的状态对象,其中待办事项已删除。

However, this still isn’t a complete picture. We have not yet covered how the reducer gets called and passed in the right action. For that, we will need to move on to define our dispatch function.

但是,这还不是完整的图片。 我们尚未介绍在正确的操作中如何调用和传递reducer。 为此,我们将继续定义调度功能。

6.定义调度,将它们附加到将触发调度的位置(即事件侦听器等) (6. Define the dispatch, attach these to where the dispatches will be triggered (ie event listeners etc))

The dispatch function is a method of the store which is used to trigger a change in the state. Any event or anything which needs to update the state must call the dispatch method to do so. This is the only way to trigger a change/update to the state. Dispatch is called and the action object is passed in (or the action creator if that was used). Once a dispatch is triggered the store then calls the reducer function and passes in the action that the dispatch provided which updates the state, as we’ve seen earlier.

调度功能是存储的一种方法,用于触发状态更改。 任何事件或任何需要更新状态的事物都必须调用dispatch方法来执行。 这是触发状态更改/更新的唯一方法。 调用Dispatch并传递操作对象(或使用操作创建者)。 一旦触发了调度,商店便会调用reducer函数,并传递调度所提供的操作来更新状态,如前所述。

Below we define the bottom half of our Components render method. We create our buttons which will contain our event handlers. Inside those, we will define our dispatch functions.

在下面,我们定义了组件渲染方法的下半部分。 我们创建包含事件处理程序的按钮。 在这些内部,我们将定义我们的调度功能。

The first button is a simple add button. This button will dispatch the add_todo action to the store. It will pass in the current user input as the value (this is the todo item that the reducer appends to the new state). Note we call dispatch as this.props.dispatch. It’s a bit out of the scope of this guide to understand how and why this gets passed as a prop to the component. So just know that it does and we can call it like this.

第一个按钮是一个简单的添加按钮。 此按钮将将add_todo操作调度到商店。 它将作为值传递当前用户输入(这是化简器附加到新状态的待办事项)。 注意,我们将调度称为this.props.dispatch 。 了解如何以及为什么将它作为道具传递给组件超出了本指南的范围。 因此,只要知道它确实可以,我们就可以这样称呼它。

The second event handler is written as an onClick on our rendered todo item. By clicking on any todo item on the page it triggers an event handler. The event handler searches the list of todos and finds the index of that todo in the list. It then dispatches the remove_todo action and passes in the index.

第二个事件处理程序被编写为渲染的待办事项上的onClick。 通过单击页面上的任何待办事项,它会触发事件处理程序。 事件处理程序搜索待办事项列表,并在列表中找到该待办事项的索引。 然后,它调度remove_todo操作并传递索引。

The cycle for how to update the state in the Redux store is now fully defined. We know that any time we want to change the state we need to call the dispatch method, pass in the appropriate action, and ensure our reducer handles those actions and returns the new state using any values we passed in via the action.

现在已完全定义了如何在Redux存储中更新状态的周期。 我们知道,每当要更改状态时,我们都需要调用dispatch方法,传递适当的操作,并确保我们的reducer处理这些操作并使用通过操作传递的任何值返回新状态。

The only puzzle piece missing now is how do we get the state from the Redux store. You’ve probably noticed that I’ve mapped over a list called this.props.todos in the previous example. You may be wondering where that came from. You may also recall at the beginning of this guide I mentioned that passing store into the Provider component is not enough to gain access to the state in the store. This is all addressed in the next 2 steps as we define our mapStateToProps function and pass that into the connect function.

现在唯一缺少的难题是如何从Redux商店获取状态。 您可能已经注意到,在上一个示例中,我已映射到名为this.props.todos的列表上。 您可能想知道那是哪里来的。 您可能还记得在本指南的开头我提到过,将存储传递到Provider组件不足以获取对存储中状态的访问。 在定义我们的mapStateToProps函数并将其传递给connect函数时,将在接下来的2个步骤中解决所有问题。

7.定义mapStateToProps函数 (7. Define the mapStateToProps function)

When you want your component to have access to the state you have to explicitly specify what in the state the component will get access to. Your component will not have access to state without this.

当您希望组件可以访问状态时,必须明确指定组件可以访问的状态。 否则,您的组件将无法访问状态。

mapStateToProps is a function which simply returns an object that defines what state should be passed into the component by assigning values in the state to properties you define in this object. Essentially, the object you return in the mapStateToProps is what your props will be in your component. The mapStateToProps function is passed into the connect method as the first argument.

mapStateToProps是一个函数,它简单地返回一个对象,该对象通过将状态中的值分配给在此对象中定义的属性来定义应将什么状态传递到组件中。 本质上,您在mapStateToProps中返回的对象就是您的prop将在组件中的内容。 mapStateToProps函数作为第一个参数传递到connect方法中。

The mapStateToProps takes the entire state as a parameter and you take only what you need from it. Here though as our state only contains the list of todos. We need that list in our ToDo component, we will return the entire state as a property called todos.

mapStateToProps将整个状态作为参数,而您只需要它所需要的。 尽管这里我们的州只包含待办事项清单。 我们需要在T​​oDo组件中使用该列表,然后将整个状态作为名为todos的属性返回。

As you can see now, we have access to our entire todos list in our props as this.props.todos. This is how we were able to render all our todos in the previous example by mapping over it.

如您现在所见,我们可以在道具中以this.props.todos访问整个this.props.todos列表。 这就是我们能够通过映射上一个示例来渲染所有待办事项的方式。

Finally we need to pass this function into our connect method to connect everything together.

最后,我们需要将此函数传递到connect方法中,以将所有内容连接在一起。

8.导出connect函数,传入mapStateToProps和null作为2个参数,并在第二对括号中传递组件名称 (8. Export the connect function, passing in mapStateToProps and null as the 2 arguments and passing the component name in the second pair of brackets)

Connect is a method that hooks up mapStateToProps and mapDispatchToProps (see below) functions to your component so that the store can read those functions and ensure what you defined in there gets passed into the component as props. This method has a special syntax which looks like this:

Connect是一种将mapStateToProps和mapDispatchToProps函数(请参见下文)连接到您的组件的方法,以便商店可以读取这些函数并确保您在其中定义的内容作为prop传递到组件中。 此方法具有特殊的语法,如下所示:

connect(mapStateToProps, MapDispatchToProps)(YourComponent)

connect(mapStateToProps, MapDispatchToProps)(YourComponent)

You pass in the 2 map...ToProps functions to the connect and then the name of your component inside the second pair of brackets. A typical pattern is to export the connect method instead of your component when you are exporting your component at the end of your file. For example:

您将2 map...ToProps函数传递给connect,然后在第二对括号内传递组件名称。 一种典型的模式是在文件末尾导出组件时,导出connect方法而不是组件。 例如:

export default connect(mapStateToProps, MapDispatchToProps)(YourComponent)

export default connect(mapStateToProps, MapDispatchToProps)(YourComponent)

This then acts in the same way as exporting normally except the state and dispatches will be passed in as props. mapStateToProps and mapDispatchToProps are actually optional params to connect. If you don’t want to pass one or either, put null in their place instead.

然后,它的行为与正常导出的行为相同,除了状态和调度将作为道具传递。 mapStateToProps和mapDispatchToProps实际上是要连接的可选参数。 如果您不想传递一个或两个,则将null代替。

You may be wondering where this mapDispatchToProps function has come from and why we haven’t mentioned it anywhere before here. Well, as this guide is the most simplified example of a Redux store and mapDispatchToProps isn’t strictly mandatory, I haven’t included it in our example. If you don’t pass mapDispatchToProps and pass null instead then you can still access the dispatch function in your component as we have earlier as this.props.dispatch.

您可能想知道mapDispatchToProps函数的来源以及为什么我们在此之前未提及它。 好吧,由于本指南是Redux存储的最简化示例,并且mapDispatchToProps不是严格必需的,因此我没有在示例中包含它。 如果您不传递mapDispatchToProps并传递null,那么您仍然可以访问组件中的dispatch函数,就像我们之前的this.props.dispatch

So to finish off our example app, all we have to do is export our component wrapping it with the connect function and passing in the mapStateToProps we just defined.

因此,要完成示例应用程序,我们要做的就是导出使用connect函数将其包装的组件,并传入刚刚定义的mapStateToProps。

And that’s it! That’s a complete implementation of a Redux store. See below for the working example of what we implemented.

就是这样! 这是Redux存储的完整实现。 请参阅以下有关我们实施的工作示例。

完整注释的代码示例 (Full Annotated Code Example)

App.js

App.js

Todo.js

Todo.js

I hope that this guide can simplify some of the strange and sometimes confusing details of Redux. It’s not a complete guide of Redux, as there are definitely more elements and patterns to understand. But if you can understand this guide then you are well on your way to being able to work with and install Redux in your apps.

我希望本指南可以简化Redux的一些奇怪的,有时令人困惑的细节。 它不是Redux的完整指南,因为肯定还有更多的元素和模式需要理解。 但是,如果您能理解本指南,那么您就可以很好地使用Redux并在您的应用程序中安装Redux。

翻译自: https://www.freecodecamp.org/news/a-beginners-guide-to-redux-9f652cbdc519/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392380.shtml

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

相关文章

leetcode 86. 分隔链表(链表)

给你一个链表和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例&#xff1a; 输入&#xff1a;head 1->4->3->2->5->2, x 3 输出&am…

极光推送

推送原理 IOS 通过APNs推送服务。 每个设备只要保持一个与APNs的常链接&#xff0c;服务器将要推送的消息发送给APNs&#xff0c;APNs再将消息转发到响应的手机&#xff0c;手机内置的程序再进行分发&#xff0c;到响应的APP&#xff0c;就能很好的实现推送功能 Andriod 虽然谷…

电脑通过手机上网的方法

(适用于包月CMWAP无限流量服务,只收CMWAP费用)移动手机(GPRS) CMWAP无限流量包月服务&#xff0c;可以通过手机作调制解调器&#xff0c;将手机和电脑连接用代理服务器上网. 看到了很多帖子&#xff0c;整理了一下&#xff0c;把它贴出来供大家参考。一 该方法对手机要求:1 手…

java入门学习_Java入门学习进阶知识点

Java入门学习进阶知识点入门阶段&#xff0c;主要是培养Java语言的编程思想。了解Java语言的语法&#xff0c;书写规范等&#xff0c;掌握Eclipse、MyEclipse等开发工具&#xff0c;编写Java代码的能力。学完这个阶段你应该可进行小型应用程序开发并且可以对数据库进行基本的增…

如何不认识自己

重点 (Top highlight)By Angela Xiao Wu, assistant professor at New York University纽约大学助理教授Angela Xiao Wu This blog post comes out of a paper by Angela Xiao Wu and Harsh Taneja that offers a new take on social sciences’ ongoing embrace of platform …

JDBC 数据库连接操作——实习第三天

今天开始了比较重量级的学习了&#xff0c;之前都是对于Java基础的学习和回顾。继续上篇的话题&#xff0c;《谁动了我的奶酪》&#xff0c;奉献一句我觉得比较有哲理的话&#xff1a;“学会自嘲了,而当人们学会自嘲,能够嘲笑自己的愚蠢和所做的错事时,他就在开始改变了。他甚至…

webassembly_WebAssembly的设计

webassemblyby Patrick Ferris帕特里克费里斯(Patrick Ferris) WebAssembly的设计 (The Design of WebAssembly) I love the web. It is a modern-day superpower for the dissemination of information and empowerment of the individual. Of course, it has its downsides …

leetcode 509. 斐波那契数(dfs)

斐波那契数&#xff0c;通常用 F(n) 表示&#xff0c;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1 给你 n &a…

java基本特性_Java面试总结之Java基础

无论是工作多年的高级开发人员还是刚入职场的新人&#xff0c;在换工作面试的过程中&#xff0c;Java基础是必不可少的面试题之一。能不能顺利通过面试&#xff0c;拿到自己理想的offer&#xff0c;在准备面试的过程中&#xff0c;Java基础也是很关键的。对于工作多年的开发人员…

plotly python_使用Plotly for Python时的基本思路

plotly pythonI recently worked with Plotly for data visualization on predicted outputs coming from a Machine Learning Model.我最近与Plotly合作&#xff0c;对来自机器学习模型的预测输出进行数据可视化。 The documentation I referred to : https://plotly.com/pyt…

转发:毕业前的赠言

1、找一份真正感兴趣的工作。 “一个人如果有两个爱好&#xff0c;并且把其中一个变成自己的工作&#xff0c;那会是一件非常幸福的事情。那么另外一个爱好用来做什么&#xff1f;打发时间啦。所以&#xff0c;第二个兴趣非常重要&#xff0c;在你无聊寂寞的时候越发显得它…

Python模块之hashlib:提供hash算法

算法介绍 Python的hashlib提供了常见的摘要算法&#xff0c;如MD5&#xff0c;SHA1等等。 什么是摘要算法呢&#xff1f;摘要算法又称哈希算法、散列算法。它通过一个函数&#xff0c;把任意长度的数据转换为一个长度固定的数据串&#xff08;通常用16进制的字符串表示&#xf…

css flexbox模型_完整CSS课程-包括flexbox和CSS网格

css flexbox模型Learn CSS in this complete 83-part course for beginners. Cascading Style Sheets (CSS) tell the browser how to display the text and other content that you write in HTML.在这本由83部分组成的完整课程中&#xff0c;为初学者学习CSS。 级联样式表(CS…

leetcode 830. 较大分组的位置

在一个由小写字母构成的字符串 s 中&#xff0c;包含由一些连续的相同字符所构成的分组。 例如&#xff0c;在字符串 s “abbxxxxzyy” 中&#xff0c;就含有 “a”, “bb”, “xxxx”, “z” 和 “yy” 这样的一些分组。 分组可以用区间 [start, end] 表示&#xff0c;其中…

php 匹配图片路径_php正则匹配图片路径原理与方法

下面我来给大家介绍在php正则匹配图片路径原理与实现方法&#xff0c;有需要了解的朋友可进入参考参考。提取src里面的图片地址还不足够&#xff0c;因为不能保证那个地址一定是绝对地址&#xff0c;完全的地址&#xff0c;如果那是相对的呢&#xff1f;如果地址诸如&#xff1…

java项目经验行业_行业研究以及如何炫耀您的项目

java项目经验行业苹果 | GOOGLE | 现货 | 其他 (APPLE | GOOGLE | SPOTIFY | OTHERS) Editor’s note: The Towards Data Science podcast’s “Climbing the Data Science Ladder” series is hosted by Jeremie Harris. Jeremie helps run a data science mentorship startup…

MongoDB教程-使用Node.js从头开始CRUD应用

In this MongoDB Tutorial from NoobCoder, you will learn how to use MongoDB to create a complete Todo CRUD Application. This project uses MongoDB, Node.js, Express.js, jQuery, Bootstrap, and the Fetch API.在NoobCoder的MongoDB教程中&#xff0c;您将学习如何使…

leetcode 399. 除法求值(bfs)

给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件&#xff0c;其中 equations[i] [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。 另有一些以数组 queries 表示的问题&#xff0c;其中 queries[j]…

【0718作业】收集和整理面向对象的六大设计原则

面向对象的六大设计原则 &#xff08;1&#xff09;单一职责原则——SRP &#xff08;2&#xff09;开闭原则——OCP &#xff08;3&#xff09;里式替换原则——LSP &#xff08;4&#xff09;依赖倒置原则——DIP &#xff08;5&#xff09;接口隔离原则——ISP &#xff08;…

数据科学 python_适用于数据科学的Python vs(和)R

数据科学 pythonChoosing the right programming language when taking on a new project is perhaps one of the most daunting decisions programmers often make.在进行新项目时选择正确的编程语言可能是程序员经常做出的最艰巨的决定之一。 Python and R are no doubt amon…