代码之家  ›  专栏  ›  技术社区  ›  Jwan622

这个Redux代码中发生了什么…对mapDispatchToProps、dispatch和connect感到困惑

  •  1
  • Jwan622  · 技术社区  · 6 年前

    我正在学习react教程,我有几个问题。

    function mapDispatchToProps(dispatch) {
      return bindActionCreators({ fetchWeather }, dispatch)
    }
    

    我想分解这个函数的每一部分。

    如何将动作创建者连接到容器?怎么样 this.props.fetchWeather 工作代码?是这个原因吗

    function mapDispatchToProps(dispatch) {
    

    如果是这样,这是在做什么?

      return bindActionCreators({ fetchWeather }, dispatch)
    

    它是否负责确保从动作创建者返回的动作对象向下流入中间件和缩减器?

    function mapDispatchToProps(dispatch)
    

    mapDispatchToProps

    最后,这个出口在做什么:

    export default connect(null, mapDispatchToProps)(SearchBar);
    

    Here is my whole code for reference:
    
    
    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { bindActionCreators } from 'redux';
    import { fetchWeather } from '../actions/index';
    
    class SearchBar extends Component {
      constructor(props) {
        super(props);
    
        this.state = { term: '' };
    
        this.onInputChange = this.onInputChange.bind(this);
        this.onFormSubmit = this.onFormSubmit.bind(this);
      }
    
      onInputChange(event) {
        this.setState({ term: event.target.value });
      }
    
      onFormSubmit(event) {
        event.preventDefault();
    
        this.props.fetchWeather(this.state.term);
        this.setState({ term: '' });
      }
    
      render() {
        return (
          <form onSubmit={this.onFormSubmit} className="input-group">
            <input
              placeholder="Get a five-day forecast in your favorite cities"
              className="form-control"
              value={this.state.term}
              onChange={this.onInputChange}
            />
    
            <span className='input-group-btn'>
              <button type="submit" className="btn btn-secondary">
                Submit
              </button>
            </span>
          </form>
        );
      }
    }
    
    function mapDispatchToProps(dispatch) {
      return bindActionCreators({ fetchWeather }, dispatch)
    }
    
    export default connect(null, mapDispatchToProps)(SearchBar);
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Community Egal    4 年前

    一个非常简洁的答案是:

    • mapStateToProps()
    • mapDispatchToProps() 是一个实用程序,它将帮助您的组件触发一个操作事件(分派可能导致应用程序状态更改的操作)
    • bindActionCreators() 主要用于将一些动作创建者传递给 不知道Redux ,并且您不想将dispatch或Redux存储传递给它。
    • <Provider>
    • connect() 是一个高阶组件(HOC),它允许您将Redux状态注入到常规React组件中。

    反应- JS
    雷杜- JS公司

    使用 react-redux :

    如果我们想把我们的 React 使用 Redux 商店,我们首先要让我们的应用程序知道这个商店存在。这就是我们要讨论的第一个主要部分 反应redux 图书馆,这是 Provider .

    供应商 是由 反应redux 图书馆。它只有一个目的:为其子组件提供存储。

    供应商

    使Redux商店可供用户使用 连接() 连接() <提供商> . 所以最终 connect 就这样,它把你的 反应 雷杜

    //This is the store we create with redux's createStore method
    const store = createStore(todoApp, {})
    
    // Provider is given the store as a prop
    render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('app-node')
    )
    

    道具

    • 商店 (右) ):应用程序中的单个Redux存储。
    • ( 反应元件 ):组件层次结构的根。

    Connect

    现在我们已经为应用程序提供了redux存储,现在我们可以将组件连接到它。我们之前已经确定,没有办法直接与商店互动。我们可以通过获取当前数据来检索数据 state 或者通过调度一个操作来改变它的状态(我们只能访问前面显示的redux流程图的顶部和底部组件)。这正是 连接()

    使用 连接() ,需要定义一个名为 mapStateToProps 它描述了如何转换电流 雷杜 将状态存储到要传递给正在包装的表示组件的道具中。


    除了读取状态,容器组件还可以分派操作。以类似的方式,您可以定义一个名为 mapDispatchToProps() dispatch() 方法并返回要注入到表示组件中的回调道具。


    简单的解释和一个基本的例子

    存储是一个包含整个应用程序状态的框。假设这个盒子在一个未知的位置。

    组件需要从盒子里取出一些东西,但它们只需要一些存储在盒子里的东西。组件知道他们需要从盒子里得到什么,但是他们不知道盒子在哪里。

    函数是一个过滤器,用于选择组件需要框中的哪些内容。选定的对象将成为组件属性。

    这个 MapStateTops公司 函数是不够的,因为它选择了框中所需的内容,但不知道框的位置。

    这个 连接 函数知道框的位置,并将其传递给mapstatetops函数,以便获取所需的内容。

    只返回当前状态的指定部分。 MapStateTops公司

     const mapStateToProps = (state) => {
         return { things: state.things }
    };
    

    所以现在我们可以把这个州的那部分作为 props -&燃气轮机; this.props.things


    但是如果组件想要改变状态呢?那就是 mapDispatchToProps

    简单的解释和一个基本的例子

    const mapDispatchToProps = () => {
         return {
              addThing: addThing,
              doAnotherThing: doAnotherThing
         }
    }
    

    地图调度程序 接受 dispatch 函数并针对 Redux reducer 当该函数被激发时。记住,道具不仅仅是对象,它们也可以是函数。这就是mapDispatchtoProps应用的地方。MapDispatchToProps允许您将状态更改发送到存储。一个例子是一个按钮点击触发一个刷新或自动加载的数据一旦组件被装载。

    动作创建者作为道具提供给组件,道具通常与组件中包含的事件处理程序函数相关联:

    handleOnClick() {
         this.props.addThing();
    };
    

    action 去商店。我们怎么做?我们用红宝石 .

    简单说明和基本实现 bindActionCreators() :

    将值为动作创建者的对象转换为具有相同键的对象,但将每个动作创建者包装为分派调用,以便可以直接调用它们。

    bindActionCreators的唯一用例是当您想将一些动作创建者传递给一个不知道Redux的组件,而不想将dispatch或Redux存储传递给它时。

    为了实现这一目标,我们:

    import { bindActionCreators } from 'redux';
    ...
    const mapDispatchToProps = (dispatch) => {
      return bindActionCreators({
             addThing: addThing,
             doAnotherThing: doAnotherThing
             }, dispatch);
    };
    

    这个 函数接受action creator和stores dispatch函数作为参数,并返回 派遣 函数的返回值 action creator 作为它的论据。

    再一次,把这些联系在一起是最重要的 连接() 函数,其中我们将mapDispatchToProps作为第二个参数传递。例如:

    export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
    

    当前状态 从存储区,并向存储区发送一个操作以触发 更新 状态

    现在,让我们用一点 TodoItem.js

    import { connect } from 'react-redux'
    
    const TodoItem = ({ todo, destroyTodo }) => {
      return (
        <div>
          {todo.text}
          <span onClick={destroyTodo}> x </span>
        </div>
      )
    }
    
    const mapStateToProps = state => {
      return {
        todo: state.todos[0]
      }
    }
    
    const mapDispatchToProps = dispatch => {
      return {
        destroyTodo: () =>
          dispatch({
            type: 'DESTROY_TODO'
          })
      }
    }
    
    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(TodoItem)
    

    MapStateTops公司 都是纯函数,分别提供存储状态和调度。此外,这两个函数都必须返回一个对象,然后该对象的键将作为它们所连接的组件的道具传递。

    在这种情况下, MapStateTops公司 地图调度程序 返回具有 destroyTodo 钥匙。

    todo 销毁待办事项 作为道具 TodoItem 功能部件