0
votes

I am learning and trying to understand Redux with React

I have following test code in index.js and App.js Where it reads API URL I make a request to API to get some data.

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import './index.css';
import App from './components/App';
import { createStore } from 'redux';

const initialState = {
    events: [],
    isViewingEvent : false,
    eventIndex : 0,
    eventProducts : []
}

//STORE
async function reducer(state = initialState, action) {
  switch(action.type) {
    case "GETEVENTS":
        {        
          const response = await fetch("API URL", {
              method: 'get',
              headers: {'Content-Type':'application/json','Accept': 'application/json'}
          })
          .then(function(response) {
           
              return response.json();         
          })
          console.log(response);
          return state.events = response;         
        };            
    default:
      return state;
  }
}

const store = createStore(reducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Now App.js

import { Component } from 'react';
import { connect } from 'react-redux'   

class App extends Component {

  handleOnClick() {
    this.props.dispatch({ type : "GETEVENTS" }) 
  }


render() {
   
  return   <div>
            <header>
              <button onClick={() => this.handleOnClick()}>TEST</button>
            </header>
          </div>
  }
}

const mapStateToProps = (state) => {
  console.log(state.events);
  return {
    events: state.events
  }
}

export default connect(mapStateToProps)(App);

I simply wish to test if I can update state with Clicking a button, by calling the dispatch function. dispatch function makes a API get request and should update state with its response.

I have console.log output in dispatch function to see what the response is, and it will show it correctly. I will get valid data from API.

Another console.log is at mapStateToProps function in App.js, where I'd like to get that events data as a prop from state. This will always show me undefined when I click the button. I can see I get valid response from API but I can never get that data as prop into App.js

What am I doing wrong here? I can think of that mapStateToProps happens before I get async response from API. So its mapping props before state update? But then if I click it the second time I should see data. But I dont, so Im missing something here which I do not understand.

this is my console.log output

Console output

2

2 Answers

1
votes

You are doing an API request in the reducer here, which is not only conceptually something you should not do in a reducer (side effects are not allowed to happen there), but in this case also something that is just plain impossible, because it turns the whole state slice into a promise.

You need to handle API requests & co outside the reducer in a middleware, for example a thunk. I recommend looking into the Async Logic and Data Fetching chapter of the official redux tutorial.

0
votes

You are changing the state in your reducer function directly which is the wrong way to do it as it is immutable. Read about it here: Immutable patterns redux

async function reducer(state = initialState, action) {
  ...
          console.log(response);
          return state.events = response; // here is the problem        
        };            
  ...
  }

Try one of the suggested approaches on the link provided.