我正在看这个来自this article的redux的超级基本实现的例子。我理解,除非派遣使用prevState
。首先,这个函数在哪里获得prevState?这与计数器需要的实际状态有何关系?它是否在名为prevState的状态中隐式设置另一个值?我只是很难理解状态如何实际传递给派遣,然后通过prevState反击。我认为这可能是一个功能性的编程思想,我还没有掌握。谢谢你帮我理解!
import React, { Component } from 'react';
const counter = (state = { value: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 };
case 'DECREMENT':
return { value: state.value - 1 };
default:
return state;
}
}
class Counter extends Component {
state = counter(undefined, {});
dispatch(action) {
this.setState(prevState => counter(prevState, action));
}
increment = () => {
this.dispatch({ type: 'INCREMENT' });
};
decrement = () => {
this.dispatch({ type: 'DECREMENT' });
};
render() {
return (
<div>
{this.state.value}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}
答案 0 :(得分:3)
<强> React.Component.prototype.setState 强>
好反应的setState
方法负责prevState
此处 - 不还原,只是为了清楚。
让我们看一下如何使用setState
。我们有 3 选项......
setState(nextState)
- 只需传递下一个状态,React会相应更新组件state
setState(nextState, callback)
- 可选地指定一旦重新呈现组件时调用的回调 - 每当state
更新时,React组件将重新呈现 - 注意:React docs通常建议使用{{ 3}}生命周期方法,而不是。setState((prevState, props) => nextState)
- 使用方便调用prevState
和props
标识符的函数调用我们来手动更新状态。预计我们提供的功能将返回下一个状态所以你有这个
this.setState(prevState => counter(prevState, action));
如果不明显,您提供的代码示例是使用#3 。因此,第一个参数prevState
将由React提供,它是组件的当前状态。这里没有使用第二个参数props
,所以我们只是忽略它(一般的想法是你可以使用道具来更新你的状态,如果相关的话)。
什么是prevState
?
究竟是什么prevState
?我们确定它是组件的当前状态,我们之前在计数器中初始化为
state = counter(undefined, {});
// => { value: 0 }
因此,当我们发送INCREMENT
时,我们会得到类似
this.setState(prevState => counter({value: 0}, {type: 'INCREMENT'})
在这种情况下counter
(缩减器)将返回
{value: 1}
此返回值是组件的 next 状态
重复申请setState
当然,如果我们再次INCREMENT
,我们会有类似
this.setState(prevState => counter({value: 1}, {type: 'INCREMENT'})
counter
将返回的地方
{value: 2}
成为组件的下一个状态
依旧......
“React和Redux之间的界限在哪里?”
首先,特定于React的代码是import
和扩展Counter
的{{1}}类。
“但是其他代码(Component
)是什么呢?”
关于redux的最酷的事情之一是它的虚无状态 - Redux仅作为模式存在于此代码示例中。没有counter
使用import
或redux
。 Redux在这里更多地用作redux的思想/哲学的实现 - 它是围绕这种单向数据流和可组合减速器的思想构建的。
“什么是减速机?”
reducer只是一个函数,当应用于某个状态和一个动作时,它会返回一个 new 状态。
当然react-redux
库包含一些有用的实用程序,可以更轻松地在应用程序中实现Redux的模式 - 但实际上,它们都是非常简单的函数。事实上,Redux的创建者丹·阿布拉莫夫(Dan Abramov)在egghead上有一个 awesome (FREE)系列,componentDidUpdate
,它可以一步一步地向您展示Redux的工作原理。在我看来,它是任何主题上有史以来最好的编码视频系列之一。
答案 1 :(得分:0)
prevState
是一个实际的当前状态。它没有及时返回,它只是返回你当前的状态,这将被用来构建一个新状态 - 因为在Redux和React的概念中,状态是immutable
,这意味着它永远不会被修改 - 当您发送新动作并使用减速器处理它时 - 您正在创建一个全新的对象(状态)。
答案 2 :(得分:0)
首先,请注意Class Counter 是从React的 Component 类型扩展而来的。因此,它将继承一堆属性和方法,其中一个是 setState 。
我们可以从React documentation for setState看到它需要两个参数:
setState(nextState, callback)
但在细则中它说: “第一个参数可以是一个对象(包含零个或多个要更新的键)或一个返回包含键的对象的函数(状态和道具)更新。“
在这种情况下,我们只传递一个参数,所以我们必须使用它,第一个参数是一个返回要更新的键对象的函数。
如果我们再看一下使用setState的原始代码:
this.setState(prevState => counter(prevState, action));
如果我们用es5 JavaScript语法编写它,可能会更容易阅读和理解:
this.setState(
function cb(prevstate) {
return counter(prevstate, action)
})
因此在这种情况下,“prevState”是匿名函数的参数。从理论上讲,它可以被命名为任何东西,只要你在函数体内使用相同的名称来引用它,一切都会好的。但是,将它命名为“prevState”似乎是一个非常标准的事情(这就是React文档使用的)。
如果我们将此视为纯粹的JavaScript,那么您传递给此函数的 prevState 应该是未定义的。
因此,多次触发INCREMENT操作会导致您的状态值始终为1,因为计数器函数将始终使用默认值:
state = { value: 0 }
我认为调度函数应该是这样的:
dispatch(action) {
this.setState(counter(this.state, action));
}
<强>更新强>
This link可以更好地解释它,但实际上如果你使用函数作为setState的第一个参数,那么 这个函数将把当前状态作为其参数 ,这就是 prevState 获取其价值的方式。