为什么要选择useState而不是useReducer
by Austin Malerba
奥斯汀·马勒巴(Austin Malerba)
为什么要选择useState而不是useReducer (Why you should choose useState instead of useReducer)
通过useState进行本地和全局状态管理的指南 (A guide to local and global state management via useState)
Since the introduction of the React Hooks API, I’ve seen a lot of discussion about useState
, useReducer
, and when to use one over the other. From these conversations, one would conclude that useState
is best suited for simple state with simple update logic and that useReducer
is best for complex state shapes with complex update logic.
自从引入React Hooks API以来,我已经看到了很多关于useState
, useReducer
以及何时使用useReducer
的讨论。 从这些谈话,人们会得出这样的结论useState
最适合于用简单的更新逻辑简单状态,并且useReducer
是最适合复杂形状的状态与复杂的更新逻辑。
I’m here to convince you that when wrapped in a 4 line custom hook, useState can be just as powerful as, if not more powerful than, useReducer when managing complex state.
我在这里说服您, 当包装在4行自定义挂钩中时,useState在管理复杂状态时的功能与useReducer一样强大,甚至比useReducer强大 。
I don’t like reducers. I’ve tried using them, but I always end up migrating away. Something just feels wrong about dispatching actions to trigger business logic when I could instead do so by invoking a function with arguments.
我不喜欢减速器。 我尝试过使用它们,但最终总是要移走。 当我可以通过调用带有参数的函数来调度操作来触发业务逻辑时,感觉有些不对劲。
And then there’s the fact that instead of encapsulating my business logic into functions, I’m supposed to cluster it all into one giant function partitioned by a bunch of switch cases? I’ve tried libraries such as redux-actions to alleviate this concern, but I still couldn’t deal with it. My dislike for reducers motivated me to search for a better solution.
还有一个事实是,不是将我的业务逻辑封装到函数中,而是应该将其全部聚集到一个由一堆开关盒分隔的巨型函数中? 我已经尝试使用诸如redux-actions之类的库来减轻这种担忧,但是我仍然无法解决 。 我对减速器的厌恶促使我寻求更好的解决方案。
Let’s review a few common reasons why people choose useReducer
over useState
:
让我们回顾一些人们为什么选择useReducer
不是useState
常见原因:
- So business logic can be centralized in the reducer as opposed to scattered about the component因此,业务逻辑可以集中在化简器中,而不是分散在组件上
- Reducers are pure functions that are easy to test in isolation of ReactReducer是纯函数,易于在React隔离中进行测试
Reducers allow pieces of state that depend on each other to be updated predictably (whereas multiple
useState
’s might not)精简器允许相互依赖的状态可预测地更新(而多个
useState
可能不会)
If any of these bullets are confusing, I’d recommend having a look at this article. Throughout this guide I will refer back to these items as the three benefits of reducers.
如果这些符号中的任何一个令人困惑,我建议您看一下这篇文章 。 在整个指南中,我将把这些项目称为减速器的三个优点。
第一步:构建一个例子 (Step One: Constructing an Example)
First, I’m going to show you an example that showcases the benefits of reducers I mentioned above, and then I’m going to show you how you can implement the same functionality via useState
without sacrificing any of the benefits of a useReducer
solution.
首先,我将向您展示一个示例,该示例展示了我上面提到的reducer的好处,然后将向您展示如何通过useState
实现相同功能而又不牺牲useReducer
解决方案的任何好处。
可冻结柜台 (A Freezable Counter)
To illustrate the pros/cons of useState
vs useReducer
I’m going to implement a simple counter with a twist. The counter can be incremented, but can also be frozen. If in the frozen state, incrementing the counter will not do anything.
为了说明useState
与useReducer
优缺点,我将实现一个简单的计数器。 计数器可以增加,但也可以冻结。 如果处于冻结状态,则递增计数器将不会执行任何操作。
As you can see, I’ve implemented our counter above once with useState
and once with useReducer
. However, StateCounterV1
has some issues. In fact, it doesn’t even work as expected.
如您所见,我已经使用useState
和useReducer
实现了上面的计数器。 但是, StateCounterV1
有一些问题。 实际上,它甚至无法按预期工作。
We would expect that StateCounterV1
should render <div>1
</div> because we increment the counter once, then we freeze the counter, and then we increment again. But in reality it renders
<div>2</div> because the second
invocation of increment doesn’t have access to
the new value of frozen. This illustrates
benefit #3 of
useReducer over useState.
我们希望StateCounterV1
应该呈现<div>1
</ div>,因为我们增加了一次计数器,然后冻结了计数器,然后又增加了。 但在现实中it renders
的<div> 2 </ DIV>因为牛逼he second
增量的调用没有ACC ess to
冷冻的新值。 这说明lustrates
t #3 of
优于useState。
It’s also apparent that in StateCounterV1
our logic to increment the counter resides in the component itself, but in ReducerCounter
the logic belongs to the countReducer
(benefit #1).
同样很明显,在StateCounterV1
用于递增计数器的逻辑驻留在组件本身中,但是在ReducerCounter
该逻辑属于countReducer
(收益#1)。
And lastly we see that in order to test the count logic in StateCounterV1
we would have to render it, whereas to test the logic in countReducer
, we could do so without ever having to render a component. We could test it simply by invoking it with a state and an action and ensuring it outputs the correct next state (benefit #2).
最后,我们看到,为了测试StateCounterV1
的计数逻辑,我们必须渲染它,而要测试countReducer
的逻辑,我们可以不必渲染组件就可以这样做。 我们可以简单地通过调用一个状态和一个动作并确保其输出正确的下一个状态(好处2)来对其进行测试。
第二步:崩溃状态 (Step Two: Collapsing State)
In our example, we have a state transition, increment
, that updates count
but depends on another piece of state, frozen
. In instances like this, I find it best to consolidate state. In theory we could always have a maximum of one useState
hook per component and still achieve any functionality we want to. But it’s totally okay to useState
multiple times as long as the pieces of state do not depend on each other when updating. With that said, let’s see how consolidating state can give us back benefit #3 of reducers.
在我们的示例中,我们有一个状态转换, increment
,它更新count
但取决于另一状态,即frozen
状态。 在这种情况下,我发现最好合并状态。 从理论上讲,每个组件最多可以有一个useState
挂钩,并且仍然可以实现我们想要的任何功能。 但是,多次使用useState
完全可以, 只要在更新时状态不相互依赖 。 如此说来,让我们看看巩固状态如何使我们获得减速器的第三大收益。
Now the updater passed to setState
in our increment
function is self-sufficient. It no longer needs to reach for frozen
via closure to determine how to produce the next state. Instead prevState
contains all of the state necessary to perform its update logic.
现在,在我们的increment
函数中传递给setState
的更新程序是自足的。 它不再需要通过封闭来frozen
以确定如何产生下一个状态。 相反, prevState
包含执行其更新逻辑所需的所有状态。
Because it’s self-sufficient, we no longer have a need to declare it at render time, we could instead lift it out of the component.
因为它是自给自足的,所以我们不再需要在渲染时声明它,而是可以将其从组件中取出。
When we lift state-updater declarations outside of our component, not only do we improve performance, but we prevent ourselves from accidentally depending on variables via closure like we did in StateCounterV1
. This pattern is a bit beside the point of this article, but I thought I’d mention it anyway.
当我们将state-updater声明提升到组件之外时,不仅可以提高性能,而且可以防止自己像StateCounterV1
那样通过闭包意外地依赖变量。 这种模式与本文的要点略有出入,但我认为无论如何我都会提到它。
第三步:提取业务逻辑 (Step Three: Extracting Business Logic)
At this point StateCounterV2
is still bloated with counter logic. But no worries, all we need to do is extract all of our counter business-logic into a custom hook. Let’s call it useCounterApi
.
此时, StateCounterV2
仍然StateCounterV2
了计数器逻辑。 但是不用担心,我们要做的就是将我们所有的计数器业务逻辑提取到一个自定义钩子中。 我们称它为useCounterApi
。
Now StateCounterV3
is looking good. I’d argue it looks even better than the ReducerCounter
. Not to mention this refactor was straightforward because all it really took was a copy/paste of our counter logic into a custom hook. But here’s where things get tricky.
现在StateCounterV3
看起来不错。 我认为它看起来比ReducerCounter
更好。 更不用说此重构很简单,因为它真正要做的只是将我们的计数器逻辑复制/粘贴到自定义钩子中。 但是,这里变得棘手。
It can be hard sometimes, as developers, to identify where logic belongs. Our brains are erratic and there are some days where it wouldn’t occur to me to extract this logic out of the component into a custom counter hook. That’s why we developers need opinionated interfaces to guide us in the right direction.
作为开发人员,有时可能很难确定逻辑的位置。 我们的大脑动荡不定,在某些日子里,我通常不会将这种逻辑从组件中提取到自定义计数器挂钩中。 这就是为什么我们的开发人员需要审慎的界面来指导我们朝着正确的方向发展。
第四步:创建指导 (Step Four: Creating Guidance)
If we had to describe useCounterApi
verbally, we’d probably say,
如果我们不得不口头描述useCounterApi
,我们可能会说,
“It’s a custom hook that creates and returns a counter API.”
“这是一个创建并返回计数器API的自定义钩子。”
Here within lies our first clue. It creates and returns an API. Thus, it is an API Factory. More specifically, it is a Counter API Factory.
我们的第一个线索就在这里。 它创建并返回一个API 。 因此,它是一个API工厂。 更具体地说,它是Counter API Factory。
But we like to abstract things, so the next question is, how can we make a Generic API Factory? Well, let’s remove the “Counter” part from useCounterApi
. Now we’re left with useApi
. Awesome, now we have our Generic API Factory. But where does our business logic go?
但是我们喜欢抽象事物,所以下一个问题是,我们如何才能创建通用 API工厂? 好吧,让我们从useCounterApi
删除“ Counter”部分。 现在我们剩下了useApi
。 太好了,现在我们有了通用API工厂。 但是我们的业务逻辑去哪儿了?
Let’s think more about how useReducer
works.
让我们更多地考虑useReducer
工作方式。
const [state, dispatch] = useReducer(reducer, initialArg, init);
The first argument of useReducer
is a reducer and the second argument is the initial state. Remember that the reducer contains business logic. Let’s try to mimic this interface.
useReducer
的第一个参数是减速器,第二个参数是初始状态。 请记住,reducer包含业务逻辑。 让我们尝试模仿这个界面。
const api = useApi(someApiFactoryFunction, initialArg);
Okay, it feels like we’re getting close to a solution. But now we have to figure out what the heck someApiFactoryFunction
is supposed to do.
好的,感觉就像我们正在接近解决方案。 但是现在我们必须弄清楚someApiFactoryFunction
应该做什么。
Well, we know it should contain business logic and we know it should be unaware of React so that we can test it without having to render a component. What we also know is that someApiFactoryFunction
cannot contain a useState
invocation because then it would be aware of React things. But it surely needs state
and setState
. So we’ll have to inject state
and setState
some other way. So how do we inject things into functions again? Oh yeah, parameters. Tying this thought exercise together, we end up with the following.
好吧,我们知道它应该包含业务逻辑,并且我们应该知道它不知道React,以便我们可以测试它而无需呈现组件。 我们还知道的是someApiFactoryFunction
不能包含useState
调用,因为这样它将知道React事物。 但是它肯定需要state
和setState
。 因此,我们将不得不以其他方式注入state
和setState
。 那么,我们如何将事物再次注入函数呢? 哦,是的,参数。 将这一思想练习结合在一起,我们得出以下结论。
And there it is. useApi
is our magical 4 line custom hook that reveals the true power of useState
. API Factory functions supply us with the current state
and a setState
callback and let us expose an API from them. Let’s think about what kind of benefits we just introduced with this simple contract change.
在那里。 useApi
是我们神奇的4行自定义钩子,它揭示了useState
的真正力量。 API Factory函数为我们提供当前state
和setState
回调,并让我们从中公开API。 让我们考虑一下我们通过这种简单的合同变更所带来的好处。
counterApiFactory
is unaware of React, which means we can now test it simply by passing a state
object and a setState
callback (Reducer benefit #2 achieved).
counterApiFactory
不了解React,这意味着我们现在可以简单地通过传递state
对象和setState
回调(实现Reducer好处#2)来对其进行测试。
useApi
expects an API Factory, which means we’re telling the developer they need to write API Factory functions with the signature ({state, setState}) =>
api . This means, even on my off days when my brain struggles to recognize that a cluster of logic can be refactored into a stateful API, I have this nice little use
Api function prompting me to throw all of my stateful business logic into a centralized location.
useApi
需要一个API Factory,这意味着我们要告诉开发人员他们需要使用签名({state, setState}) =>
api来编写API Factory函数。 这意味着,即使在我休假的日子里,当我的大脑难以识别可以将逻辑集群重构为有状态的API时,我也会le use
Api函数很好地提示我将所有有状态的业务逻辑都放在一个集中的位置。
第五步:优化 (Step Five: Optimizing)
As it stands, useApi
isn’t as efficient as it could be. Any component that consumes useApi
will invoke useApi
on every render, which means apiFactory
will also be invoked on every render. It’s not necessary to invoke apiFactory
on each render, but rather only when state
has changed. We can optimize useApi
by memoizing the execution of apiFactory
.
就目前而言, useApi
效率不如useApi
。 任何消耗useApi
组件useApi
将在每个渲染useApi
上调用useApi
,这意味着apiFactory
也将在每个渲染器上被调用。 不必在每个渲染apiFactory
上调用apiFactory
,而仅在state
更改时调用。 我们可以通过useApi
的执行来优化apiFactory
。
测试API工厂 (Testing an API Factory)
Now that we’ve implemented our useApi
hook, let’s look at how we’d test an API Factory.
现在我们已经实现了useApi
挂钩,让我们看一下如何测试API工厂。
It’s simple enough to create a wrapper around our counterApiFactory
that mimics the behavior of state
/setState
. With this helper function we can test our counterApiFactory
in a very natural way.
在我们的counterApiFactory
周围创建一个模仿state
/ setState
行为的包装器非常简单。 使用此辅助函数,我们可以非常自然地测试我们的counterApiFactory
。
useApi vs useReducer (useApi vs useReducer)
Let’s now compare these two solutions.
现在让我们比较这两种解决方案。
逻辑封装 (Logic Encapsulation)
In both solutions, logic to update state is centralized which allows for easy reasoning, debugging, and testing. However reducers only provide a mechanism to update state, they do not provide a mechanism to retrieve state. Instead it’s common to write selectors and apply them downstream from the reducer. What’s nice about our useApi
solution is that it encapsulates not only logic to update state, but also logic to retrieve state ?.
在这两种解决方案中,用于更新状态的逻辑都是集中的,这使得推理,调试和测试变得容易。 但是,reduce只提供更新状态的机制,而没有提供检索状态的机制。 取而代之的是编写选择器并将其应用到减速器的下游。 我们的useApi
解决方案的useApi
是,它不仅封装了更新状态的逻辑,而且还封装了检索状态的逻辑?
更新状态 (Updating State)
To update state with useReducer
, we need to dispatch actions. To update state with useApi
we need to invoke updater methods. A potential advantage of reducers in this scenario is that multiple reducers could listen to the same action. However, this also comes with a downside: execution flow is not intuitive once an action has been dispatched. If I need multiple, disparate pieces of state to be updated at once, I’d rather do it explicitly with multiple back-to-back API method calls, than through a single dispatched action that’s broadcasted to all reducers.
要使用useReducer
更新状态,我们需要调度动作。 要使用useApi
更新状态,我们需要调用updater方法。 在这种情况下,Reducer的潜在优势是多个Reducer可以侦听同一动作。 但是,这也有一个缺点:一旦分派了动作,执行流程就不直观。 如果我需要一次更新多个不同的状态,我宁愿使用多个背对背API方法调用来显式地进行此操作,而不是通过广播到所有reducer的单个调度动作来显式地进行更新。
性能 (Performance)
One nice thing about reducers is that, via reducer composition, multiple reducers can listen to a single dispatched action which means you can have many parts of the state change in just a single render. I have not come up with a solution for API Factory composition (though it’s surely possible). For now my solution is to invoke state updaters back-to-back when necessary which could lead to more renders than a reducer approach.
关于化简器的一件好事是,通过化简器组成,多个化简器可以侦听单个调度的动作,这意味着您可以在单个渲染中拥有状态变化的许多部分。 我还没有想出API工厂组合的解决方案(尽管肯定有可能)。 现在,我的解决方案是在必要时背靠背调用状态更新程序,这可能比reducer方法导致更多的渲染。
样板 (Boilerplate)
Reducer-based solutions are notoriously boilerplate-y (especially when working with redux). Action type declarations take up some extra space and dispatching actions tends to be a bit more verbose than just invoking a function with arguments. For these reasons I’d say useApi
has a slight edge on useReducer
in terms of boilerplate code.
众所周知,基于Reducer的解决方案非常简单(尤其是在使用redux时)。 动作类型声明会占用一些额外的空间,而分派动作往往比仅带参数的函数更为冗长。 由于这些原因,我会说useApi
有一个轻微的边缘useReducer
中的样板代码方面。
可测性 (Testability)
Both reducers and API Factories are easy to test.
减速器和API工厂都易于测试。
进一步探索用途 (Further Exploring useApi)
Let’s have a look at some other cool things we can do with useApi
.
让我们来看看我们可以使用useApi
其他一些酷操作。
I’ve taken the time to implement the classic Redux Todo List Example via useApi
. Here’s how todosApiFactory
looks in the useApi implementation.
我已经花了一些时间通过useApi
实现经典的Redux Todo List Example 。 这是todosApiFactory
在useApi实现中的外观。
One gross thing you may have noticed in the code above is the repetition of the following boilerplate.
您可能在上面的代码中注意到的一件事是重复以下样板。
setState(prevState => ({ ...prevState, /* … */});
Assuming our state
is an object and because setState
does not support shallow merging, we need to do this to ensure we preserve any state that we’re not currently working with.
假设我们的state
是一个对象,并且因为setState
不支持浅层合并 ,那么我们需要执行此操作以确保保留当前不使用的任何状态。
We can reduce some of this boilerplate and get some other cool benefits from a library called immer. immer is an immutability library that lets you write immutable code in a mutable way.
我们可以减少一些样板,并从名为immer的库中获得其他一些很酷的好处。 immer是一个不变性库,可让您以可变的方式编写不变的代码。
As you can see, immer helps us remove some of that annoying boilerplate code required when writing immutable updates. But beware, the convenience of immer is also its Achilles’ heel. A developer who’s introduced to the concept of immutability through immer might not fully understand the consequences of mutations.
如您所见,沉浸式帮助我们删除了编写不可变更新时所需的一些烦人的样板代码。 但是要注意,沉浸的便利性也是它的致命弱点。 通过沉浸式引入不变性概念的开发人员可能不会完全了解突变的后果。
But wait a second, useApi
only provides state locally, but the Todo List Example uses redux to provide a global state solution.
但是请稍等, useApi
仅在本地提供状态,但“ 待办事项列表示例”使用redux提供全局状态解决方案。
具有API Factories
全球商店 (Global Stores with API Factories
)
Let’s see how we can create global stores from API Factories.
让我们看看如何从API工厂创建全局商店。
Not bad at all, right? Context makes global state super easy in React. So we now have a global state management solution to use with API Factories.
一点都不差吧? 上下文使React中的全局状态变得异常简单。 因此,我们现在有了一个可以与API工厂一起使用的全局状态管理解决方案。
Below is the working API Factory Todo List Example.
以下是有效的API Factory Todo List示例。
结论 (Conclusion)
To wrap it up, this article contains three functions that you might find useful.
总结一下,本文包含三个可能会有用的功能。
These functions provide useful abstractions for local and global state management powered by useState
.
这些功能为useState
支持的本地和全局状态管理提供了有用的抽象。
Don’t get me wrong, reducers come with a lot of perks, but I just can’t rest easy with the interface they offer. Both useApi
and useReducer
offer viable solutions to complex state management. It’s really a matter of preference.
不要误会我的意思,Reducer带来很多好处,但是我只是对它们提供的界面感到不安。 useApi
和useReducer
为复杂的状态管理提供可行的解决方案。 这实际上是一个偏好问题。
One useful takeaway is that libraries don’t have to perform complex logic to be useful. A lot of the value libraries and frameworks offer does not have to do with the logic they perform, but rather the guidance they give the developer. Good libraries/frameworks force the developer to follow known patterns via explicit and opinionated interfaces. useApi
does very little computationally, but encourages the developer put their stateful business logic in a centralized location, all the while avoiding pollution of components.
一个有用的收获是,库不必执行复杂的逻辑就可以使用。 许多价值库和框架提供的值与它们执行的逻辑无关,而与它们给开发人员的指导有关。 好的库/框架迫使开发人员通过显式且自觉的界面遵循已知的模式。 useApi
在计算上做的很少,但是鼓励开发人员将其有状态业务逻辑放在一个集中的位置,同时还要避免组件污染。
翻译自: https://www.freecodecamp.org/news/why-you-should-choose-usestate-instead-of-usereducer-ffc80057f815/
相关文章:

php 类中的变量的定义
php 如果在类中定义变量,在类的方法中调用时应该加上$this-> . class ClassName {private $a 333;function __construct(){$this->a 2222;}public function bbb($value){echo $this->a;} } $b new className(); echo $b->bbb();转载于:https://www.c…

微信小程序云数据库触底分页加载,下拉无限加载,第一次请求数据随机,随机获取数据库的数据
效果图 小程序云开发分页加载代码 <!--pages/chatList/chatList.wxml--> <view class"pageTitle">家博慧</view> <view class" search_arr"><icon class"searchcion" size16 typesearch></icon><input …

Linux(Centos)之安装Java JDK及注意事项
1.准备工作 a.因为Java JDK区分32位和64位系统,所以在安装之前必须先要判断以下我们的Centos系统为多少位系统,命令如下: uname -a解释:如果有x86_64就是64位的,没有就是32位的。后面是X686或X86_64则内核是64位的&…

2019web前端趋势_2019年最值得关注的Web开发趋势
2019web前端趋势by Mrudul Shah通过Mrudul Shah 2019年最值得关注的Web开发趋势 (Top Web Development trends to look out for in 2019) Do you know that nearly 200 websites are pushed out every minute? Sounds astonishing right? But it is a fact and that’s why …

WPF入门教程系列九——布局之DockPanel与ViewBox(四)
七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中。停靠面板其实就是在WinForm类似于Dock属性的元 素。DockPanel会对每个子元素进行排序,并停靠在面板的一侧&…

tabBar 自定义,小程序自定义底部导航栏
创建一个自定义组件 my_tab,组件代码在后面,先看调用自定义组件的代码,比如我需要在index 页面调用,就在index.json中引用组件,index.json 代码(引用的路径为你创建的自定义组件路径) {"n…

2015年最新出炉的JavaScript开发框架
前端框架简化了开发过程中,像 Bootstrap 和 Foundation 就是前端框架的佼佼者。在这篇文章了,我们编制了一组新鲜的,实用的,可以帮助您建立高质量的 Web 应用程序的 JavaScript 框架清单。 1.Aurelia Aurelia是下一代JavaScript客…

小程序前端性能测试_如何提高前端应用程序的性能
小程序前端性能测试If your website takes longer than 3 seconds to load, you could already be losing nearly half of your visitors.如果您的网站加载时间超过3秒,则可能已经失去了将近一半的访问者。 Yes this is a fact, proven by several research studie…

10-TypeScript中的接口
接口是一种规约的约定,从接口继承的类必须实现接口的约定。在高级开发中,通常接口是用于实现各种设计模式的基础,没有接口,设计模式无从谈起。 定义接口: interface ILog{recordlog():boolean; } 类从接口继承…

样式集(六)仿微信通讯录样式
效果图: 这里有引用到 自定义底部导航,自定义底部导航组件链接 <!--pages/chatList/chatList.wxml--><!-- <include src"/components/common/common" /> --> <view class"top"><view class"pageTi…

WCF动态添加ServiceKnownType
WCF中传输自定义类型时,必须在服务接口类(服务协定)上加上ServiceKnownType(typeof(yourClass)), 在实际应用中比较麻烦,可以用动态的办法来实现动态添加。 服务接口类,加上一行 [ServiceKnownType("GetKnownType…

博客 rss 如何使用_如何使用RSS从您的GatsbyJS博客自动交叉发布
博客 rss 如何使用With the recent exodus from Medium many developers are now creating their own GatsbyJS Blogs and then cross-posting to Medium or publications like freecodecamp.org and dev.to.随着Medium最近的离职,许多开发人员现在正在创建自己的Ga…

大型技术网站的技术( 高并发、大数据、高可用、分布式....)(一)
面对高并发、大流量、高可用、海量数据、用户分布广泛、网络情况复杂这类网站系统我们如何应对??? 第一阶段 一台服务器不行就上多台服务器 1.应用程序与数据服务分离 将应用程序、数据库、文件等资源放在一台服务器上,面对海量…

BestCoder Round #65 B C D || HDU 5591 5592 5593
B 题意:ZYB在远足中,和同学们玩了一个“数字炸弹”游戏:由主持人心里想一个在[1,N][1,N]中的数字XX,然后玩家们轮流猜一个数字,如果一个玩家恰好猜中XX则算负,否则主持人将告诉全场的人当前的数和XX比是偏大还是偏小&a…

数组去重,ES6数组去重 new Set()
普通数组去重 var b [...new Set([1,2, 3, 4, 5, 5, 5, 5])]console.log(b); 输出结果: 包含对象的数组去重 var o {a:1}var b [...new Set([o, o, 3, 4, 5, 5, 5, 5])]console.log(b); 输出结果: 包含对象的数组去重有一个坑 var b [...new Set([{…

使用angular的好处_在项目中使用Angular的最大好处
使用angular的好处by Irina Sidorenko伊琳娜西多连科(Irina Sidorenko) 在项目中使用Angular的最大好处 (The top benefits of using Angular for your project) 在项目实施中使用Angular的11个理由及其好处 (11 reasons to use Angular and its benefits for your project im…

python之路——模块和包
一、模块 1、什么是模块? 常见的场景:一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名字加上.py的后缀。 但其实import加载的模块分为四个通用类别: 1、使用Python编写的代码(.py文件) 2、…

夺命雷公狗---linux NO:3 centos_mini版的安装和备份
废话不多说,和前面的其实是差不多的,如下图所示: 安装其实是和桌面版的差不多的,但是经典版的不能自定义分区(如详细区,如home之类的)。。。 因为我们使用的是命令行方式的所以直接选英文&#…

快速学习 async await 的使用, Demo 解析
async 和 await 字面都很好理解,分别是异步和等待。 来两个简单的 demo, demo1 tt2(){return new Promise(rps>{setTimeout(() > {rps(true)}, 1500);})},async tt1(){var a await this.tt2();console.log(a)},/*** 生命周期函数--监听页面加载*…

小型工作室创业项目_为什么新开发人员应该在小型创业公司工作
小型工作室创业项目In my first year of working in the industry (6 months as an intern, 6 months as a full-time employee), I worked at startups that were less than 10 people large. I was one of the only 2 or 3 developers, and usually one of the first. Throug…

head first python菜鸟学习笔记(第六章)
1. Python提供字典,允许有效组织数据,将数据与名关联,从而实现快速查找,而不是以数字关联。 字典是内置数据结构,允许将数据与键而不是数字关联。这样可以使内存中的数据与实际数据的结构保持一致。?&#…

小程序聊天室开发,发送文字,表情,图片,音频,视频,即时通讯,快速部署,可定制开发
效果图: 微信小程序聊天功能模块,现在已经支持发送图片,文字,音频,视频,表情,在线即时聊天啦。 需要做的可以联系我微信。13977284413 上代码: <view class"bo">…

常用浏览器插件
modify headers :firefox的IP伪造插件 httpRequester:firefox的模拟http请求插件JSON-handle:chrome格式化json插件firebug:firefox查看http请求工具firepath:firefox中获取元素路径转载于:https://www.cnblogs.com/xx…

编码中统一更该变量的快捷键_更多项目想法,以提高您的编码技能
编码中统一更该变量的快捷键Two weeks ago I published an article containing 15 project ideas that you can build to level up your coding skills, and people were very excited about that resource.两周前,我发表了一篇文章,其中包含15个项目构想…
My97DatePicker日历控件日报、每周和每月的选择
My97DatePicker日历控件日报、每周和每月的选择 1、设计源代码 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><h…

DotNet Core Console 程序使用NLog
参考:https://github.com/NLog/NLog/wiki/Tutorial 步骤: 1. 使用Nuget安装NLog.Extensions.Logging Install-Package NLog.Extensions.Logging 2.编写代码(到这步运行代码,不报错,但是也不会有log输出,因为…

小程序判断用户在线状态
在页面的两个生命周期组件里面 onShow() {console.log(-----上线线)let info wx.getStorageSync(chat_item)DB.collection(friends).where({_id: info._id}).get().then(res > {console.log(-----, res)if (res.data[0].a wx.getStorageSync(userInfo)._openid) {console.…

react.js做小程序_如何使用React.js构建现代的聊天应用程序
react.js做小程序In this tutorial, I will guide you to build your own group chat application using React, React Router, and CometChat Pro. Yes, rather than roll out our own server, we will instead use CometChat Pro to handle the real-time sending and receiv…

RAP Mock.js语法规范
Mock.js 的语法规范包括两部分: 数据模板定义规范(Data Template Definition,DTD)数据占位符定义规范(Data Placeholder Definition,DPD)1.数据模板定义规范 DTD 数据模板中的每个属性由 3 部分…

NSDictionary、NSMutableDictionary基本使用
郝萌主倾心贡献,尊重作者的劳动成果。请勿转载。假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠Cocos2d-X源代码下载:点我传送游戏官方下载:htt…