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!