反应 Redux 分页

React Redux Pagination

案例一: 我在 rails 中做了一个简单的服务器端分页,并使用 react 作为前端,使用 redux 作为我的状态管理。我已经完成了所有的事情,剩下的最后一件事就是传递新生成的 url 并获取新数据。该数据将在另一个将生成和产品的组件中获取。 由于我在我的案例中使用的是 redux,我如何才能将这些数据传递给我的数据获取操作?

案例二: 我尝试传递一个名为 url 的参数,并使用我提供给它的 url 数据再次分派获取操作。但是 return 是调度不是函数。我什至可以在 action.jsx 中重新运行操作吗?

action.jsx
    
    export const handlePage = (e, { activePage }) => {
        let pageNum = activePage
        let pageString = pageNum.toString();
        let url = "/api/v1/products/index/?page=" + pageString; ------> Use This ...
    }
    

export const fetchProducts = (url) => { ------> In Here
        return (dispatch) => {
            console.log(url);
            dispatch(fetchProductsRequest());
            axios
              .get(url) 
              .then((response) => {
                // response.data is the products
                const products = response.data.products;
                dispatch(fetchProductsSuccess(products));
              })
              .catch((error) => {
                // error.message is the error message
                dispatch(fetchProductsFailure(error.message));
              });
        };
    };

    export class Paginator extends React.Component {
      state = {
        page: [],
        pages: [],
      };
    
    
      componentDidMount() {
        axios
          .get("/api/v1/products/index", { withCredentials: true })
          .then((response) => {
            this.setState({
              page: response.data.page,
              pages: response.data.pages,
            });
          })
          .catch((error) => {
            console.log("Check Login Error", error);
          });
      }
    
      render() {
        return (
          <div>
            <Pagination count={this.state.pages} page={this.state.page} onChange={handlePage} />
          </div>
        );
      }
    }

Product.jsx

import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import "../../style/frequentlyasked.scss";
import ItemOne from "../../files/Item-One.png";

// Redux
import { connect } from "react-redux";
import { loadCurrentItem, addToCart, fetchProducts } from "./action";

const Product = ({
  mapProducts,
  fetchProducts,
  product,
  addToCart,
  loadCurrentItem,
}) => {
  useEffect(() => {
    fetchProducts();  -----> Using it Here !
  }, []);

  return (
    <div className="card-deck d-flex justify-content-center">
      {mapProducts.map((product) => (
        <div className="card item-card" key={product.id} product={product}>
          {/* Admin Card */}
          {/* Header Image */}
          <img className="card-img-top" src={ItemOne} alt="Card image cap" />
          {/* Card Body */}
          <div className="card-body">
            <h4 className="card-title">{product.title}</h4>
            <h5 className="card-title">$ {product.price}</h5>
            <p className="card-text">{product.description}</p>
            <button
              className="btn btn-primary"
              onClick={() => addToCart(product.id)}
            >
              + Add To Cart
            </button>
            <a href="#" className="btn btn-danger">
              <svg
                width="1em"
                height="1em"
                viewBox="0 0 16 16"
                className="bi bi-heart-fill"
                fill="currentColor"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  fillRule="evenodd"
                  d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"
                />
              </svg>
            </a>
          </div>
          {/* Card Footer */}
          <div className="card-footer">
            <small className="text-muted">Last updated 3 mins ago</small>
          </div>
        </div>
      ))}
    </div>
  );
};

const mapStateToProps = (state) => {
  return {
    mapProducts: state.shop.products,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    addToCart: (id) => dispatch(addToCart(id)),
    loadCurrentItem: (item) => dispatch(loadCurrentItem(item)),
    fetchProducts: () => dispatch(fetchProducts()),
  };
};

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

你的情况:


  useEffect(() => {
    fetchProducts(page);  -----> Using it Here !
  }, [page]);

//and


    fetchProducts: (page) => dispatch(fetchProducts(page)),

请注意,您的 mapDispatchToProps 也可以(并且应该)以地图对象表示法编写:

const mapDispatchToProps = {
  addToCart,
  loadCurrentItem,
  fetchProducts
}

另请注意,官方建议使用react-redux hooks代替connectmapDispatchToProps

所以跳过整个 connect 内容并在您的组件中:

const Product = ({
  product,
}) => {
  const mapProducts = useSelector(state => state.shop.products)
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(fetchProducts(page));
  }, []);

此外,如果您仍在使用 connect,您可能一直在学习过时的教程。 Redux 在过去几年发生了很大变化。查看 modern redux and the up-to-date official redux tutorials

顺便说一下:官方 redux 工具包有一个新的 API,它可以为您处理所有数据获取。你已经可以试用了,目前作为一个额外的包:https://rtk-query-docs.netlify.app/