React component does not call connect redux function

Viewed 42

I have a weird problem with the connection of the component and redux store. While I have 2 component(siblings) one can connect to redux store (Pets.js) the other does not(FeedList.js)

I will try to explain as much as I can.

From top-to-bottom struct here is my project.

App.js:

import React, { Component, Fragment } from "react";
import { HashRouter as Router, Route, Switch } from "react-router-dom";

import { Provider as AlertProvider } from "react-alert";
import AlertTemplate from "react-alert-template-basic";

// Components
import Header from "./layout/Header";
import Dashboard from "./pets/Dashboard";
import Alerts from "./layout/Alerts";
import Login from "./accounts/Login";
import Register from "./accounts/Register";
import PrivateRoute from "./common/PrivateRoute";
import MainFeed from "./feed/MainFeed";

import { Provider } from "react-redux";
import store from "../store";
import { loadUser } from "../actions/auth";

const alertOptions = {
  timeout: 3000,
  position: "top center",
};

class App extends Component {
  componentDidMount() {
    store.dispatch(loadUser);
  }

  render() {
    return (
      <Provider store={store}>
        <AlertProvider template={AlertTemplate} {...alertOptions}>
          <Router>
            <Fragment>
              <Header />
              <Alerts />
              <div className="container">
                <Switch>
                  <PrivateRoute exact path="/" component={Dashboard} />
                  <PrivateRoute
                    exact
                    path="/feed"
                    component={MainFeed}
                    {...store}
                  />
                  <Route exact path="/register" component={Register} />
                  <Route exact path="/login" component={Login} />
                </Switch>
              </div>
            </Fragment>
          </Router>
        </AlertProvider>
      </Provider>
    );
  }
}
export default App;
// ReactDOM.render(<App />, document.getElementById("app"));

My custom Route Component is the PrivateRoute where I pass the props to other comps.

PrivateRoute.js:

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
    {...rest}
    render={(props) => {
      if (auth.isLoading) {
        return <h2>Loading...</h2>;
      } else if (!auth.isAuthenticated) {
        return <Redirect to="/login" />;
      } else {
        console.log(props);
        return <Component {...props} />;
      }
    }}
  />
);

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

export default connect(mapStateToProps, null, null, { pure: false })(
  PrivateRoute
);

Ok here comes the weird part of the problem in the Dashboard component which renders the Pets component everything is fine and it connects to the store.

Dashboard.js:

import React, { Fragment } from "react";
import Form from "./Form";
import Pets from "./Pets";

export default function Dashboard() {
  return (
    <Fragment>
      <Form />
      <Pets />
    </Fragment>
  );
}

Pets.js

import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { getPets, deletePet, getAllPets } from "../../actions/pets";

import UserPetsStyle from "../../style/LayoutStyle";
import DeleteIcon from "@material-ui/icons/Delete";

import {
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from "@material-ui/core";

export class Pets extends Component {
  static propTypes = {
    pets: PropTypes.array.isRequired,
    getPets: PropTypes.func.isRequired,
    deletePet: PropTypes.func.isRequired,
    getAllPets: PropTypes.func.isRequired,
  };

  componentDidMount() {
    console.log(this.props);
    this.props.getPets();
  }

  render() {
    const classes = UserPetsStyle;
    return (
      <Fragment>
        <h2>Pets</h2>
        <TableContainer component={Paper}>
          <Table className={classes.table} aria-label="simple table">
            <TableHead>
              <TableRow>
                <TableCell align="right">ID</TableCell>
                <TableCell align="right">Name</TableCell>
                <TableCell align="right">Race</TableCell>
                <TableCell align="right">Create At</TableCell>
                <TableCell align="right">Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {this.props.pets.map((pet) => (
                <TableRow key={pet.id}>
                  <TableCell align="right">{pet.id}</TableCell>
                  <TableCell align="right">{pet.name}</TableCell>
                  <TableCell align="right">{pet.race}</TableCell>
                  <TableCell align="right">{pet.created_at}</TableCell>
                  <TableCell align="right">
                    <DeleteIcon
                      onClick={this.props.deletePet.bind(this, pet.id)}
                      className="btn btn-danger btn-sm"
                    />
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      </Fragment>
    );
  }
}

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

export default connect(mapStateToProps, { getPets, deletePet, getAllPets })(
  Pets
);

While my MainFeed/FeedList does not even call the connect function.

MainFeed.js:

import React, { Fragment } from "react";
import { FeedList } from "../feed/FeedList";

export default function MainFeed() {
  return (
    <Fragment>
      <FeedList />
    </Fragment>
  );
}

FeedList.js

import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import UserPetsStyle from "../../style/LayoutStyle";

import { getAllPets } from "../../actions/pets";
import {
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from "@material-ui/core";

export class FeedList extends Component {
  static propTypes = {
    pets: PropTypes.array.isRequired,
    getAllPets: PropTypes.func.isRequired,
  };

  componentDidMount() {
    console.log(this);
    // this.props.getAllPets();
  }

  render() {
    const classes = UserPetsStyle;
    return (
      <Fragment>
        <h2>Pets</h2>
        <TableContainer component={Paper}>
          <Table className={classes.table} aria-label="simple table">
            <TableHead>
              <TableRow>
                <TableCell align="right">ID</TableCell>
                <TableCell align="right">Name</TableCell>
                <TableCell align="right">Race</TableCell>
                <TableCell align="right">Create At</TableCell>
                <TableCell align="right">Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {/* {this.props.pets.map((pet) => (
                <TableRow key={pet.id}>
                  <TableCell align="right">{pet.id}</TableCell>
                  <TableCell align="right">{pet.name}</TableCell>
                  <TableCell align="right">{pet.race}</TableCell>
                  <TableCell align="right">{pet.created_at}</TableCell>
                  <TableCell align="right"></TableCell>
                </TableRow>
              ))} */}
            </TableBody>
          </Table>
        </TableContainer>
      </Fragment>
    );
  }
}

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

export default connect(mapStateToProps, { getAllPets })(FeedList);

So any ideas?

To help you further I have tried the withRouter method and the {pure:false} option at connect func but nothings seems to change.Also while using reduxDevTools and DevTools it seems like mapStateToProps is not called at FeedList.js component.

Thanks for your time!

2 Answers

the second argument of connect dispatch should be send like this:

const mapDispatchToProps = dispatch => {
  return {
    // dispatching plain actions
    getAllPets: () => dispatch(getAllPets())
   
  }
}

I actually solved it. The problem was that i was importing the componet FeedaList with brackets ( {FeedList} ) while i shouldnt.

Related