【问题标题】:Dispatch Redux action in React在 React 中调度 Redux 操作
【发布时间】:2017-11-09 23:27:56
【问题描述】:

我正在尝试使用 FetchAPI 和 Redux 获取测试 API。

问题在于调度 redux 操作。

这是我的代码:

ProductList.js
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as productActions from '../actions/product';
import RaisedButton from 'material-ui/RaisedButton';

function fetchProductsWithRedux() {
    console.log("fetchProductsWithRedux-1");
    return (dispatch) => {
        console.log("fetchProductsWithRedux-2");
        dispatch(this.props.action.fetchProdutcsRequest());
        return fetchProdutcs().then(([response, json]) => {
            if (response.status === 200) {
                console.log("success");
                dispatch(this.props.action.fetchProductsSucesss(json))
            }
            else {
                console.log("error");
                dispatch(this.props.action.fetchProductsError())
            }
        })
    }
}

function fetchProdutcs() {
    const URL = "https://jsonplaceholder.typicode.com/posts";
    return fetch(URL, { method: 'GET' })
        .then(response => Promise.all([response, response.json()]));
}


class ProductList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            productList: [
                'product 1',
                'product 2',
                'product 3'
            ]
        }
    }
    componentDidMount() {
        fetchProductsWithRedux();
    }
    render() {
        return (
            <div className="ProductList">
                <h2>Products</h2>
                <ul>
                    {
                        this.props.posts &&
                        this.props.posts.map((post) => {
                            return (
                                <li>{post.title}</li>
                            )
                        })
                    }
                </ul>

                <ol>
                    <RaisedButton label="Get Products Action" onClick={this.props.action.getProducts} />
                </ol>
            </div>
        );
    }
}

function mapStateToProps(state, props) {
    return {
        product: state.product,
        posts: state.posts
    };
}
function mapDispatchToProps(dispatch) {
    return {
        action: bindActionCreators(productActions, dispatch)
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(ProductList);

product.js(操作)

export function fetchProductsRequest() {
  console.log('fetchProductsRequest');
  return {
    type: 'FETCH_PRODUCTS_REQUEST'
  }
}

export function fetchProductsSuccess(payload) {
  console.log('fetchProductsSuccess');
  return {
    type: 'FETCH_PRODUCTS_SUCCESS'
  }
}

export function fetchProductsError() {
  console.log('fetchProductsError');
  return {
    type: 'FETCH_PRODUCTS_ERROR'
  }
}

product.js(减速器)

export default(state = [], payload) => {
    switch (payload.type) {
        case 'FETCH_PRODUCTS_REQUEST':
            console.log('FETCH_PRODUCTS_REQUEST action');
            return state;
        case 'FETCH_PRODUCTS_SUCCESS':
            console.log('FETCH_PRODUCTS_SUCCES action');
            return {...state, posts: payload.payload}
        default:
            return state;
    }
};

store.js

import { createStore } from 'redux';
import rootReducer from './reducers';

export default(initialState) => {
    return createStore(rootReducer, initialState);
}

Product.js (pages, component)
import React, { Component } from 'react';
import ProductList from '../../components/ProductList';
import RaisedButton from 'material-ui/RaisedButton';
//import './Product.css';

class Product extends Component {
    render() {
        return (
            <div className="Product">
                <h1>ProductList Page</h1>
                <RaisedButton label="Default" />
                <ProductList />
            </div>
        );
    }
}
export default Product;

console.log("fetchProductsWithRedux-2");从未到达 ProductList.js 中。

怎么了?有任何想法吗?提前致谢。

【问题讨论】:

  • 你应该使用redux-thunk中间件。将其应用到商店。

标签: reactjs redux react-redux dispatch


【解决方案1】:

您似乎错过了来自“redux-thunk”的导入 thunk。如果您不使用任何中间件,例如“redux-thunk”,则无法在 redux 操作中返回函数

【讨论】:

    【解决方案2】:

    您的代码存在一些问题。

    首先,fetchProductsWithRedux 是一个动作,因此您需要调度它而不是直接调用它。正如 Bjoern 提到的,你调用它的方式,函数调用只是返回一个函数,它永远不会被调用。

    现在,您不能在当前场景中调度它,因为它返回一个函数,而不是对象。要解决这个问题,您必须使用 redux-thunk,这将允许它调度一个函数。

    您可以将它添加到 mapDispatchToProps,就像您为 getProducts 所做的那样,但是有一个简写方式。在您的 mapDispatchToProps 中,您可以执行以下操作:-

     const mapDispatchToProps = { fetchProductsWithRedux, getProducts }
    

    你会注意到它只是返回一个带有 2 个函数的对象。

    来自文档:

    如果传递了一个对象,则假定其中的每个函数都是 Redux 动作创建者。具有相同函数名称但每个动作创建者都包装在调度调用中以便可以直接调用它们的对象将被合并到组件的道具中。

    因此,它将完全按照您之前使用 bindActionCreators 所做的那样做,但它看起来更优雅。现在,您可以使用onClick={this.props.getProducts} 而不是onClick={this.props.action.getProducts}。注意缺少的action.

    此外,您的导入将更改为

    import { getProducts } from '../actions/product';
    

    现在,要解决您的问题,在 componentDidMount 中,而不是直接调用该函数,您必须这样做:-

    componentDidMount() {
       this.props.fetchProductsWithRedux();
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:
      function fetchProductsWithRedux() {
      console.log("fetchProductsWithRedux-1");
      return (dispatch) => {
          console.log("fetchProductsWithRedux-2");
          ...
          }
      

      这会返回一个函数function(dispatch){...},它没有被调用

      componentDidMount() {
          fetchProductsWithRedux();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-18
        • 2018-02-16
        • 2020-05-30
        • 2020-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-06
        相关资源
        最近更新 更多