首页 > 解决方案 > React 组件不调用 connect redux 函数

问题描述

我对组件和 redux 存储的连接有一个奇怪的问题。虽然我有 2 个组件(兄弟姐妹),但一个可以连接到 redux 商店(Pets.js),另一个不能(FeedList.js)

我会尽力解释。

从上到下的结构是我的项目。

应用程序.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 组件,一切都很好,并且连接到商店。

仪表板.js:

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

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

宠物.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 甚至没有调用连接函数。

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。

谢谢你的时间!

标签: javascriptreactjsreact-reduxreact-routerreact-router-dom

解决方案


连接调度的第二个参数应该像这样发送:

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

推荐阅读