简体   繁体   中英

Data not being fetched (React-redux)

Hi so I'm doing a project with spotify api and I'm trying to get new releases. The data is being passed down to the reducer however when I call the fetch action in my App component and try to console.log the new releases (this.props.newAlbums) it's empty. Fetching user data still works, but fetching new releases doesn't.

This is my fetch action in actions/index.js.

export const fetchUserData = (accessToken) => (dispatch) =>{
    fetch('https://api.spotify.com/v1/me', {
        headers: {'Authorization': 'Bearer ' + accessToken}})
            .then(response => response.json())
            .then(data => 
                dispatch({
                    type:"FETCH_USER_DATA",
                    payload: data
          })
        );
};
export const fetchNewAlbums = (accessToken) => dispatch =>{
    fetch('https://api.spotify.com/v1/browse/new-releases?limit=5',{
        headers:{'Authorization': 'Bearer ' + accessToken}})
            .then(res => res.json())
            .then(albums =>
                dispatch({
                    type:"FETCH_NEW_ALBUMS",
                    payload:albums.albums.items
            })
        );
}

This is the reducer for new releases (newAlbumReducer.js)

    const initialState={
    albums:null
}

    const newAlbumReducer = (state=initialState,action)=>{
        switch(action.type){
            case "FETCH_NEW_ALBUMS":
                return{
                    ...state,
                    albums:action.payload
                };
            default:
                return state;
        }
    }
    export default newAlbumReducer; 

My store

import {createStore, applyMiddleware} from "redux";
import rootReducer from "../reducers/rootReducer";
import thunk from "redux-thunk";
import logger from "redux-logger";

const initialState = {};

const store = createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk)
);
export default store;

And my App.js

import React, {Component} from 'react';
import "../css/style.css";
import queryString from 'query-string';
import {connect} from "react-redux";
import PropTypes from "prop-types";
import {fetchUserData,fetchNewAlbums} from "../actions/index.js";
import SignInButton from "../components/SignInButton";
import SearchBar from "../components/SearchBar";
import MusicCards from "../components/Cards/MusicCards";
class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      isShowAlbumsClicked:false
    };
    this.handleSignIn = this.handleSignIn.bind(this);
    this.handleShowAlbumsClick = this.handleShowAlbumsClick.bind(this);
  }
  componentDidMount(){
    let parsed = queryString.parse(window.location.search);
    let accessToken = parsed.access_token;
    if(!accessToken){
      return;
    }
    this.setState({
      accessToken:accessToken
    })

    this.props.fetchUserData(accessToken);
    this.props.fetchNewAlbums(accessToken);
    console.log(this.props.newAlbums);
  }
  handleSignIn(e){
    e.preventDefault();
    window.location=window.location.href.includes('localhost') ? 'http://localhost:8888/login':'https://something.herokuapp.com/login'
  }
  handleShowAlbumsClick(e){
    this.setState({
      isShowAlbumsClicked:!this.state.isShowAlbumsClicked
    })
  }
  render(){
      return (
        <div className="app">
          {this.props.userData ?
          <div>
            <h1 style={{'fontSize': '40px', 'marginTop':'1%'}}>
              Welcome {this.props.userData.display_name} to Find Your Music
            </h1>
            <SearchBar/>
            {this.state.isShowAlbumsClicked ?
            <div>
              <MusicCards/>
            </div> : <h2 onClick={this.handleShowAlbumsClick}>Show</h2>
          }
          </div> : <SignInButton handleSignIn={this.handleSignIn}/>
          }
        </div>
      );
  }
}
App.propTypes={
  fetchUserData:PropTypes.func.isRequired,
  fetchNewAlbums:PropTypes.func.isRequired,
  userData:PropTypes.object,
  newAlbums:PropTypes.object
}

const mapStateToProps = (state) =>{
  return{
    userData: state.userData.data,
    newAlbums: state.newAlbum.albums
  };
};
const mapDispatchToProps = {
    fetchUserData,
    fetchNewAlbums
}
export default connect(mapStateToProps, mapDispatchToProps)(App);

So it looks like you already have redux-thunk installed but you are not using it. I see you passed thunk to apply middleware in create store, that's good.

Try something like this in your action creator.

export const fetchNewAlbulms = (accessToken) => async dispatch => {
    const response = await fetch('https://api.spotify.com/v1/browse/new-releases?limit=5',{headers:{'Authorization': 'Bearer ' + accessToken}}) 

    dispatch({
       type:"FETCH_NEW_ALBUMS",
       payload:albums.albums.items
    })
}

or this (same thing)

export const fetchNewAlbulms = (accessToken) => {
    return async dispatch => {
        const response = await fetch('https://api.spotify.com/v1/browse/new-releases?limit=5',{headers:{'Authorization': 'Bearer ' + accessToken}}) 

        dispatch({
           type:"FETCH_NEW_ALBUMS",
           payload:albums.albums.items
        })
    }
}

Your reducer should not need any updating.

This will wait to dispatch until it gets a response.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM