1

without redux it works so that not a api connection problem

I have an express app connected to react with proxy I have already managed to display my data in react but now i want to make that in redux soo:

There is my problem, i have maked all the reducers/action, store and combine reducer but I didn't see any datas in my page and i haven't any errors

There is my code :

Action

export const api = ext => `http://localhost:8080/${ext}`;

//
// ─── ACTION TYPES ───────────────────────────────────────────────────────────────
//

export const GET_ADVERTS = "GET_ADVERTS";
export const GET_ADVERT = "GET_ADVERT";

//
// ─── ACTION CREATORS ────────────────────────────────────────────────────────────
//

export function getAdverts() {
  return dispatch => {
    fetch("adverts")
      .then(res => res.json())
      .then(payload => {
        dispatch({ type: GET_ADVERTS, payload });
      });
  };
}

export function getAdvert(id) {
  return dispatch => {
    fetch(`adverts/${id}`)
      .then(res => res.json())
      .then(payload => {
        dispatch({ type: GET_ADVERT, payload });
      });
  };
}

reducer

import { combineReducers } from "redux";
import { GET_ADVERTS, GET_ADVERT } from "../actions/actions";
const INITIAL_STATE = {
  adverts: [],
  advert: {}
};

function todos(state = INITIAL_STATE, action) {
  switch (action.type) {
    case GET_ADVERTS:
      return { ...state, adverts: action.payload };
    case GET_ADVERT:
      return { advert: action.payload };
    default:
      return state;
  }
}

const todoApp = combineReducers({
  todos
});

export default todoApp;

index.js

//imports
const store = createStore(todoApp, applyMiddleware(thunk));

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>,

  document.getElementById("app")
);

My advertlist page :

//imports..

class Adverts extends Component {


  componentDidMount() {
    this.props.getAdverts();
  }

  render() {
    const { adverts = [] } = this.props;

    return (
      <div>
        <Header />
        <h1>Adverts</h1>
        {adverts.map(advert => (
          <li key={advert._id}>
            <a href={"adverts/" + advert._id}>
              {advert.name} {advert.surname}
            </a>
          </li>
        ))}

        <Footer />
      </div>
    );
  }
}

const mapStateToProps = state => ({
  adverts: state.adverts
});

export default connect(
  mapStateToProps,
  { getAdverts }
)(Adverts);
Benjamin Barbé
  • 281
  • 2
  • 4
  • 16

2 Answers2

4

I think your problem is here:

function mapStateToProps(state) {
  return {
    **adverts: state.adverts**
  };
}

It should work if you change state.adverts to state.todos.adverts:

function mapStateToProps(state) {
  return {
    adverts: state.todos.adverts
  };
}

Because your reducer is called todos, and it has state { adverts }, that's why you cannot access adverts even tho they are obtained.

You can check out working version here: https://codesandbox.io/s/olqxm4mkpq

Vikky
  • 750
  • 8
  • 16
1

The problem is, when you just create a store with one reducer without using combine reducer, it is possible to refer it directly in the ContainerS, like this:

const mapStateToProps = state => {
    
    return{
        *name of var*:  state.adverts   /*direct refers to adverts*/
    }
}

But, when it use combined-reducer , it has to refer to an exact reducer that you want to use.like this :

const mapStateToProps = state => {
    
    return{
        *name of var* :  state.todos.adverts   (indirect refers to adverts from combined-reducer todos)
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103