在异步调用axios API后使用React Hook和Redux的SetState

时间:2019-12-11 11:16:46

标签: javascript reactjs redux react-redux axios

我正在从带有axios的服务器上获取产品,并在 CatalogProducts 组件中呈现数据,如下所示:

const CatalogProducts = props => {
  const classes = useStyles();

  const [data, setData] = useState([]);

  const fetchProducts = async () => {
    await props.getProducts();
  };

  useEffect(async () => {
    fetchProducts();
    setData(props.products);
  }, []);

  const { products } = props.products;

  const items = products.map((product, index) => {
    return (
      <Grid item xs={12} sm={6} md={3} key={index}>
        <CatalogProduct product={product} />
      </Grid>
    );
  });

  if (products.length === 0) {
    return <p>Loading ...</p>;
  } else {
    return (
      <Container maxWidth="xl" className={classes.root}>
        <Grid
          container
          direction="row"
          justify="center"
          alignItems="center"
          spacing={3}
        >
          {items}
        </Grid>
      </Container>
    );
  }
};

const mapStateToProps = state => {
  return {
    products: state.products
  };
};

const mapDispatchToProps = dispatch => ({
  getProducts: () => dispatch(actions.getProductsAction())
});

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

我可以使用 props.products 访问产品数据,但是当我想使用 data 变量访问它们时,我不知道这是一个好主意与setData()吗?

1 个答案:

答案 0 :(得分:1)

在功能组件内部,您可以使用新的useDispatchuseSelector功能,这些功能更易于使用。

您可以用这个替换您的CatalogProducts代码,导入其他必要的导入并尝试吗?

import React, { useEffect, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
//other imports

const CatalogProducts = () => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const products = useSelector(state => state.products);
  console.log("Products: ", products);

  const fetchProducts = useCallback(() => {
    dispatch(actions.getProductsAction());
  }, [dispatch]);

  useEffect(() => {
    fetchProducts();
  }, [fetchProducts]);

  const items = products.map((product, index) => {
    return (
      <Grid item xs={12} sm={6} md={3} key={index}>
        <CatalogProduct product={product} />
      </Grid>
    );
  });

  if (!products) {
    return <p>Loading ...</p>;
  } else if (products.length === 0) {
    return <div>No products found</div>;
  } else {
    return (
      <Container maxWidth="xl" className={classes.root}>
        <Grid
          container
          direction="row"
          justify="center"
          alignItems="center"
          spacing={3}
        >
          {items}
        </Grid>
      </Container>
    );
  }
};

export default CatalogProducts;

使用jsonplaceholder假api来示例codesandbox