在Redux中获取数据时,操作有效负载将返回未定义状态

时间:2019-04-24 19:49:58

标签: reactjs redux fetch redux-thunk

我正在通过React应用程序移植以使用Redux。我可以看到该动作是在click事件上触发的,但是当我将console.log添加到化简器中的动作时,我看到了一个未定义的值。

由于使用提取API提取JSON数据,因此我使用Redux thunk。

generateQuote操作应返回一个新的报价。

我正在做的任何事情显然是错误的吗?

reducers / quotes.js


const defaultState = 
{ quote: 'Hello World',
  name: 'Me',
  email: 'foo@bar.com',
  date: Date(Date.now()),
  generatedQuotes: []

 }

const quotes = (state = defaultState, action) => {
  switch(action.type) {
    case GENERATE_QUOTE : 
      console.log(action.payload)
      return { ...state, quotes: action.payload, date: action.date } 
    case DELETE_QUOTE : 
        return {
          generatedQuotes: [...state.generatedQuotes.filter(quote => quote !== action.payload)]}
    case SHARE_QUOTE : 
          return state;
    default: 
      return state;
  }
}

export default quotes;

actions / index.js

export const generateQuote = () => dispatch => {
  const randomNum = (Math.floor(Math.random() * (500 - 1)) + 1);
  fetch(`https://jsonplaceholder.typicode.com/comments?id=${randomNum.toString()}`)
  .then(res => res.json())
  .then(data => {
    return 
    dispatch( {
      type: GENERATE_QUOTE, 
      payload: data[0],
      date: Date(Date.now())
    })
  })
}

Quote.js(组件)

/* eslint-disable react/require-default-props */
/* eslint-disable react/button-has-type */
/* eslint-disable react/jsx-filename-extension */
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

const Quote = ({quote, author, email, date, generateQuote, shareQuote}) => {

  return (
    <div className="box">
      <p>
        <strong>Quote:</strong>
        {' '}
        {quote}
      </p>
      <p>
        <strong>Author:</strong>
        {' '}
        {author}
      </p>
      <p>
        <strong>Email:</strong>
        {' '}
        {email}
      </p>
      <p>
        <strong>Date:</strong>
        {' '}
        {date}
      </p>
      <br />
      <div className="buttons">
        <button className="button is-primary is-small" onClick={generateQuote}>New Quote</button>
        <button className="button is-success is-small" onClick={shareQuote}>Tweet Quote</button>
      </div>

    </div>
  );
};

Quote.propTypes = {
  quote: PropTypes.string,
  author: PropTypes.string,
  email: PropTypes.string,
  date: PropTypes.string,
  generateQuote: PropTypes.func,
  shareQuote: PropTypes.func,
};

const mapStateToProps = state => {
  const { quote, author, email, date} = state;
};

const mapDispatchToProps = dispatch => {
  return {
    generateQuote: () => dispatch({type: 'GENERATE_QUOTE'}),
    shareQuote: () => dispatch({type: 'SHARE_QUOTE'})
  };
}

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

2 个答案:

答案 0 :(得分:0)

我认为缺少return语句:

export const generateQuote = () => dispatch => {
  const randomNum = (Math.floor(Math.random() * (500 - 1)) + 1);
  return fetch(`https://jsonplaceholder.typicode.com/comments?id=${randomNum.toString()}`)
  .then(res => res.json())
  .then(data => 
    dispatch({
      type: GENERATE_QUOTE, 
      payload: data[0],
      date: Date(Date.now())
  }) 
 ).catch(error => console.log(error))
}

如果错误仍然存​​在,请尝试使用用于测试的静态数字请求:

https://jsonplaceholder.typicode.com/comments?id=1

答案 1 :(得分:0)

看起来您需要在组件中调度quote操作。您要分派两次到减速器。一次在组件中,另一个在动作文件中。动作文件中的功能是否真的被触发了?

以下示例。

https://jsonplaceholder.typicode.com/comments?id=101用一个数组来响应,

[
   {
      postId: 21,
      id: 101,
      ....
   }
] 

很酷。静态数有效。您提取的逻辑是正确的。

我很好奇的是,是否正在调用/触发您的实际提取。在您的组件中,您正在调用mapStateToProps的generateQuote的值=> dispatch({type: 'GENERATE_QUOTE'}),就像这样……

const mapDispatchToProps = dispatch => {
  return {
    generateQuote: () => dispatch({type: 'GENERATE_QUOTE'}),
    shareQuote: () => dispatch({type: 'SHARE_QUOTE'})
  };
}

然后,您要在actions/index.js

的generateQuote中再次 分发它

我可能缺少一些东西,但是您可能一起跳过了动作。

// ...are you sure this is firing? 
// console.log's never killed a cat. 
dispatch({
  type: GENERATE_QUOTE, 
  payload: data[0],
  date: Date(Date.now())
})

我会将您的操作放入mapStateToProps()函数中,就像这样……

import QuoteActions from '../actions"

// ... blah blah blah

const mapDispatchToProps = (dispatch) => {
  return {
    fetchProfile: (credentials) => {
      dispatch(QuoteActions.generateQuote()) // << HERE
    }
  }
}

希望这会有所帮助。