Fripo
Fripo

Reputation: 173

Get data from Redux thunk

I've just started implementing Redux in a React application, and it's the first time i try to, so please bear with me. My problem is that i can't access the data in my component this this.props.questions

I have a simple action which is supposed to async fetch some data

export function fetchQuestions(url) {
    const request = axios.get('url');

    return (dispatch) => {
        request.then(({data}) => {
            dispatch({ type: 'FETCH_QUESTIONS', payload: data });
            console.log(data);
        });
    };
}

Which is picked up my reducer questions_reducer

export default function(state = [], action) {
   switch(action.type) {
       case 'FETCH_QUESTIONS':
           console.log('Getting here');
           return state.concat([action.payload.data]);
           console.log('But not here');
   }
   return state;
}

My index reducer looks like this:

import { combineReducers } from 'redux';
import fetchQuestions from './question_reducer';

const rootReducer = combineReducers({
    questions: fetchQuestions
});

export default rootReducer;

I pass it to my store where i apply the thunk middleware and finally into <Provider store={store}> which wraps my app, but the prop just returns undefined in my React component

configureStore:

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

export default function configureStore(initialState) {
    return createStore(
        rootReducer,
        initialState,
        applyMiddleware(thunk)
    );
}

I don't know if the console.log is to be trusted but it logs from my questions_reducer before the data is returned from the dispatch in my action

EDIT (Component)

class QuestionsRoute extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }

    componentDidMount() {
       this.props.fetch('someUrl);
       setTimeout(function(){ console.log(this.props.questions) }, 
       1500);
    }

    render() {
       {console.log(this.props.questions)}
       return (
          <div>
             <1>Hello</1>
                {this.props.questions !== undefined ?
                   <p>We like props</p>: <p>or not</p>
                }
            </div>
        );
    }
};

const mapStateToProps = (state) => {
    return {
        questions: state.questions,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        fetch: () => dispatch(fetchQuestions())
    };
};

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

Upvotes: 1

Views: 1644

Answers (1)

Rob Hogan
Rob Hogan

Reputation: 2624

In your reducer

export default function(state = [], action) {
   switch(action.type) {
       case 'FETCH_QUESTIONS':
           return state.concat([action.payload.data]);
   }
   return state;
}

You should probably instead have return state.concat([action.payload]);

Since from dispatch({ type: 'FETCH_QUESTIONS', payload: data }); we see that payload is data, it doesn't contain it.

Update: I'd recommend setting up redux-devtools / redux-devtools-extension / react-native-debugger so you can visually see your actions and store state live - makes things like this a lot easier to debug!

Upvotes: 2

Related Questions