简体   繁体   中英

Async API Call, Redux React-Native

I have recently started to learn React-Native and I am trying to implement Redux to manage the state of my app.

As I have experience with React JS I implemented the state manage Redux the same way I would usually do with React JS. Everything seems to work except the async api call. The props in store change but it does not change in component props.

Here is how I set my redux store

import { createStore, compose, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import reducer from './reducers';

//create initial state 
const initialState = {};

//create a variable that holds all the middleware
const middleware = [thunk, logger];

//create the store
const store = createStore(
  reducer,
  initialState,
  compose(
    applyMiddleware(...middleware)
  )
);

export default store;

My reducer component

import { FETCH_REQUEST_BEGIN, FETCH_REQUEST_FAILED, DATA_FETCHED} from '../constants';


const initialState = {
  movieResults: null,
  fetching : false,
  failed : false
}

export default (state = initialState, actions)=>{

  switch(actions.type){

    case FETCH_REQUEST_BEGIN:
      return  {
        ...state,
        fetching : true
      };
    case DATA_FETCHED : 
      return {
        ...state,
        movieResults : actions.payload,
        fetchin : false
      }
    case FETCH_REQUEST_FAILED:
      return  {
        ...state,
        failed : true
      };
    default : 
      return state;
  }
}

This is the root reducer

import { combineReducers } from 'redux';
import movieReducer from './movieReducer';


export default combineReducers({
  movie : movieReducer
});

action component

import axios from 'axios';

import { FETCH_REQUEST_BEGIN, FETCH_REQUEST_FAILED } from '../constants';

const apiRequest = (url, type) => {
  return dispatch => {
    dispatch({
      type : FETCH_REQUEST_BEGIN
    });

    axios.get(url)
      .then((results) => {
        dispatch({
          type : type,
          payload : results.data
        });
      }).catch((error) => {
        dispatch({
          type : FETCH_REQUEST_FAILED,
          payload : error
        });
      });
  }
}

export default apiRequest;

Main component

import React, { Component } from 'react';
import { View, Text, Button, ActivityIndicator } from 'react-native';
import { API, DATA_FETCHED } from '../constants';
import { apiRequest } from '../actions';
import { connect } from 'react-redux';

class Home extends Component {

  componentWillMount() {
    const discoverUrlMovies =`https://jsonplaceholder.typicode.com/posts`;
    this.fetchData(discoverUrlMovies, DATA_FETCHED);
  }

  fetchData = (url, type) => {
    this.props.apiRequest(url, type);
  }

  shouldComponentUpdate(nextProps, prevProps){
    return nextProps != prevProps
  }

  render() {
    const { movie }  = this.props;

    //console out the props
    console.log('this.props', this.props);

    let displayMovies;

    if(movie === undefined || movie === null ){
      displayMovies = <ActivityIndicator size = 'large' color = '#121222'/>
    }else {
      displayMovies = <Text>Working</Text>
    }
    return (
      <View style = {{flex: 1}}>
        <Text>Home</Text>
        {
          //display result 
          displayMovies
        }
      </View>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    movie : state.movieResults
  }
}
export default connect(mapStateToProps, { apiRequest })(Home);

What am I missing / doing wrong?

图片

You need to define your mapStateToProps func as

movie : state.movie.movieResults

since you're combining them as

export default combineReducers({
  movie : movieReducer
});

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