了解Redux的基本实现prevState是如何使用的?

时间:2017-02-27 20:09:24

标签: javascript reactjs functional-programming redux react-redux

我正在看这个来自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>
    )
  }
}

3 个答案:

答案 0 :(得分:3)

<强> React.Component.prototype.setState

好反应的setState方法负责prevState此处 - 还原,只是为了清楚。

让我们看一下如何使用setState。我们有 3 选项......

  1. setState(nextState) - 只需传递下一个状态,React会相应更新组件state
  2. setState(nextState, callback) - 可选地指定一旦重新呈现组件时调用的回调 - 每当state更新时,React组件将重新呈现 - 注意:React docs通常建议使用{{ 3}}生命周期方法,而不是。
  3. setState((prevState, props) => nextState) - 使用方便调用prevStateprops标识符的函数调用我们来手动更新状态。预计我们提供的功能将返回下一个状态
  4. 所以你有这个

    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使用importredux。 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 获取其价值的方式。