【问题标题】:React component does not call connect redux functionReact 组件不调用 connect redux 函数
【发布时间】:2021-02-24 08:42:18
【问题描述】:

组件和 redux 存储的连接有一个奇怪的问题。 虽然我有 2 个组件(兄弟姐妹),但一个可以连接到 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 甚至没有调用连接函数。

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。

感谢您的宝贵时间!

【问题讨论】:

    标签: javascript reactjs react-redux react-router react-router-dom


    【解决方案1】:

    connect dispatch 的第二个参数应该是这样发送的:

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

    【讨论】:

    • 如果你的意思是在最后一个组件 FeedList.js ,那么什么都不会发生。当我在 ComponentDidMount() 函数中使用 console.log(this.props) 时,props 为 null,pets[] 数组和 getAllPets 函数都没有。
    【解决方案2】:

    我真的解决了。 问题是我不应该导入带有括号 ( {FeedList} ) 的组件 FeedaList。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-18
      • 2018-11-17
      • 2016-05-28
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2018-06-06
      相关资源
      最近更新 更多