我尝试使用FetchAPI和Redux获取测试API。
问题在于dispatch 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(actions)
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(reducer)
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(&#34; fetchProductsWithRedux-2&#34;);从未到达过ProductList.js。
出了什么问题?有任何想法吗?提前谢谢。
答案 0 :(得分:2)
似乎你错过了来自&#39; redux-thunk&#39;的输入。如果您不使用任何类似于&#39; redux-thunk&#39;
的中间件,则无法在redux操作中返回函数答案 1 :(得分:1)
您的代码存在一些问题。
首先,fetchProductsWithRedux是一个动作,所以你需要调度它而不是直接调用它。正如Bjoern所提到的,你调用它的方式,函数调用只返回一个永远不会被调用的函数。
现在,您无法在当前场景中调度它,因为它返回一个函数,而不是对象。要解决这个问题,你必须使用redux-thunk,这将允许它调度一个函数。
您可以将其添加到mapDispatchToProps,就像您为getProducts所做的那样,但有一个简写。在mapDispatchToProps中,您可以执行以下操作: -
const mapDispatchToProps = { fetchProductsWithRedux, getProducts }
您会注意到它只返回一个包含2个函数的对象。
来自文档:
如果传递了一个对象,则假定其中的每个函数都是Redux动作创建者。具有相同函数名称的对象,但每个动作创建者都包含在一个调度调用中,因此可以直接调用它们,它们将合并到组件的道具中。
因此,它将完全与您之前使用bindActionCreators所做的一样,但它看起来更优雅。现在,您可以onClick={this.props.action.getProducts}
而不是onClick={this.props.getProducts}
。请注意丢失的action.
此外,您的导入将更改为
import { getProducts } from '../actions/product';
现在,为了解决您的问题,在componentDidMount中,而不是直接调用该函数,您将不得不这样做: -
componentDidMount() {
this.props.fetchProductsWithRedux();
}
希望这会有所帮助。
答案 2 :(得分:0)
function fetchProductsWithRedux() {
console.log("fetchProductsWithRedux-1");
return (dispatch) => {
console.log("fetchProductsWithRedux-2");
...
}
这将返回一个函数function(dispatch){...}
,该函数未在
componentDidMount() {
fetchProductsWithRedux();
}