reactjs 我无法从外部函数的useParams访问路径参数变量

kuarbcqp  于 2023-03-17  发布在  React
关注(0)|答案(2)|浏览(146)

我需要访问productId,一个URL中的变量,经过一点搜索,我发现useParams钩子被用来做这个。当我这样做时,我可以访问这个变量,但我需要在另一个函数mapStateToProps中使用这个变量。当我试图从其他函数访问这个变量时,它是未定义的。
AddOrUpdateProduct.js:

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { saveProduct } from "../../redux/actions/productActions";
import { getProducts } from "../../redux/actions/productActions";
import { getCategories } from "../../redux/actions/categoryActions";
import ProductDetail from "./ProductDetail";
import { useSelector } from "react-redux";
import { useParams } from "react-router-dom";

function AddOrUpdateProduct({
  products,
  categories,
  getProducts,
  getCategories,
  saveProduct,
  history,
  ...props
}) {
  let {productId} = useParams();

  const [product, setProduct] = useState({ ...props.product });

  useEffect(() => {
    if (categories.length === 0) {
      getCategories();
    }
    setProduct({ ...props.product });
  }, [props.product]);

  function handleChange(event) {
    const { name, value } = event.target;
    setProduct((previousProduct) => ({
      ...previousProduct,
      [name]: name === "categoryId" ? parseInt(value, 10) : value,
    }));
  }

  function handleSave(event) {
    event.preventDefault();
    saveProduct(product).then(() => {
      history.push("/");
    });
  }
  
  return (
    <ProductDetail
      product={product}
      categories={categories}
      onChange={handleChange}
      onSave={handleSave}
    ></ProductDetail>
  );
  
}

export function getProductById(products, productId) {
  let product = products.find((product) => product.id == productId) || null;
  return product;
}

function mapStateToProps(state) {
  const productId = this.productId;
  const product =
    productId && state.productListReducer.length > 0
      ? getProductById(state.productListReducer, productId)
      : {};
  return {
    product,
    products: state.productListReducer,
    categories: state.categoryListReducer,
  };
}

const mapDispatchToProps = {
  getCategories,
  getProducts,
  saveProduct,
};

export default connect(mapStateToProps, mapDispatchToProps)(AddOrUpdateProduct);

App.js:

import { Container } from "reactstrap";
import Navi from "../navi/Navi";
import Dashbord from "./Dashbord";
import { Routes, Route } from "react-router-dom";
import CartDetail from "../cart/CartDetail";
import AddOrUpdateProduct from "../products/AddOrUpdateProduct";
import NotFound from "../common/NotFound";

function App() {
  return (
    <Container>
      <Navi></Navi>
      <Routes>
        <Route path="/" element={<Dashbord></Dashbord>}></Route>
        <Route path="/product" element={<Dashbord></Dashbord>}></Route>
        <Route path="/cart" element={<CartDetail></CartDetail>}></Route>
        <Route
          path="/saveproduct/:productId"
          element={<AddOrUpdateProduct/>}
        ></Route>
         <Route
          path="/saveproduct"
          element={<AddOrUpdateProduct/>}
        ></Route>
        <Route  path ="*" element={<NotFound></NotFound>}></Route>
      </Routes>
    </Container>
  );
}

export default App;
deyfvvtc

deyfvvtc1#

如果你不介意的话,请阅读更多关于如何使用useSelector来使用redux数据的内容。尝试使用useEffect Hook,并在组件内调用函数getProductById****AddOrUpdateProduct.js解决这个问题的更好方法是在组件内使用钩子。你调用getProductById只是为了获取单个产品,你也可以使用useSelector钩子来获取redux状态数据。您的代码可以进一步改进。

kgqe7b3p

kgqe7b3p2#

您正在使用过时的redux代码和模式。请使用连接到redux存储的组件中的useDispatchuseSelector挂钩,而不要使用connect高阶组件。问题是this.productIdmapStateToProps函数中未定义。
重构以使用当前react-redux代码的示例:

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import { saveProduct } from "../../redux/actions/productActions";
import { getCategories } from "../../redux/actions/categoryActions";
import ProductDetail from "./ProductDetail";

function AddOrUpdateProduct() {
  const navigate = useNavigate();
  const dispatch = useDispatch();

  const { productId } = useParams();

  const products = useSelector(state => state.productListReducer);
  const categories = useSelector(state => state.categoryListReducer);
  
  const [product, setProduct] = useState(() => {
    return getProductById(products, productId) || {};
  });

  useEffect(() => {
    if (!categories.length) {
      dispatch(getCategories());
    }
  }, [categories]);

  useEffect(() => {
    if (productId && products.length) {
      setProduct(getProductById(products, productId) || {});
    }
  }, [productId, products]);

  function handleChange(event) {
    const { name, value } = event.target;

    setProduct((previousProduct) => ({
      ...previousProduct,
      [name]: name === "categoryId" ? parseInt(value, 10) : value,
    }));
  }

  function handleSave(event) {
    event.preventDefault();

    dispatch(saveProduct(product))
      .then(() => {
        navigate("/");
      });
  }
  
  return (
    <ProductDetail
      product={product}
      categories={categories}
      onChange={handleChange}
      onSave={handleSave}
    />
  );
}

export function getProductById(products = [], productId) {
  return products.find((product) => product.id === productId) || null;
}

export default AddOrUpdateProduct;

相关问题