组件和redux存储的连接出现了一个奇怪的问题。虽然我有两个组件(兄弟(,一个可以连接到redux存储(Pets.js(,另一个不能(FeedList.js(
我会尽力解释的。
从上到下的结构是我的项目。
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"));
我的自定义路由组件是PrivateRoute,在这里我将道具传递给其他组件。
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
);
好吧,这里是Dashboard组件中问题的奇怪部分,它显示Pets组件一切正常,并连接到商店。
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
);
而我的MainFeed/FeedList甚至不调用connect函数。
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);
有什么想法吗?
为了进一步帮助您,我在connect func中尝试了withRouter方法和{pure:false}选项,但似乎什么都没有改变。此外,在使用reduxDevTools和DevTools时,FeedList.js组件似乎没有调用mapStateToProps。
谢谢你抽出时间!
连接调度的第二个参数应该像这样发送:
const mapDispatchToProps = dispatch => {
return {
// dispatching plain actions
getAllPets: () => dispatch(getAllPets())
}
}
我实际上解决了它。问题是,我正在导入带括号的组件FeedaList({FeedList}(,而我不应该导入。