在 Redux 中获取数据时,操作负载 returns 未定义

Action Payload returns as undefined when fetching data in Redux

我正在移植 React 应用程序以使用 Redux。我可以看到该操作在单击事件时触发,但是当我将 console.log 添加到 reducer 中的操作时,我看到了一个未定义的值。

我正在使用 Redux thunk,因为我正在使用 API 获取 JSON 数据。

generateQuote 操作应该 return 新报价。

我所做的有没有明显错误的地方?

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);

我认为缺少 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

看来您需要在组件中发送报价操作。你两次派遣到你的减速器。一次在组件中,另一个在动作文件中。动作文件中的函数是否真的被触发了?

示例如下。

https://jsonplaceholder.typicode.com/comments?id=101 以数组响应,

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

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

我很好奇您的实际抓取是否 called/fired。在您的组件中,您正在调用 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
    }
  }
}

希望对您有所帮助。