Redux 不断更新

Redux constantly updating

我正在使用 expo 使用 React Native 构建一个应用程序,我实现了 Redux。现在在我的组件中,我需要从 API 中获取一些内容来填充列表。我决定使用 useEffect 挂钩来完成它。现在,在我的 useEffect 挂钩的依赖项数组中,我放入了我的 Redux 状态列表。像这样:

const onFetchOrders = async (query: string, offset: number, limit?: number, filter?: {}) => {
  await props.fetchOrders('', 0);

}

useEffect(() => {
  setIsLoading(true);
  onFetchOrders('', 0);

  if (props.orders.length > 0) {
    setOrders(props.orders)
  } else {
    setIsLoading(true);
  }

}, [props.orders])

订单正在映射到另一个组件中的道具:

const mapState = (state : RootState) => ({
    orders: state.orders.items,
    debtor: state.debtor.debtor,
    totalCount: state.orders.totalCount
})

const mapDispatch = (dispatch: any) => {
    return {
      fetchOrders: (query?: string, offset?: number, limit?: number, filters?: {}) => dispatch(tFetchOrders(query, offset, limit, filters)),
      fetchDebtor: (uuid: string) => dispatch(thunkFetchDebtor(uuid)),
      fetchCredentials: () => dispatch(thunkFetchCredentials()),
    };
  }

//const connector = connect(mapState, mapDispatch)(Root);
export const connector = connect(mapState, mapDispatch);

export type OrdersProps = ConnectedProps<typeof connector> & OrderStackNavProps<"Orders">;

现在,如果我启动应用程序,我的 useEffect 挂钩会不断重新呈现,因为订单数组中似乎有更新。

每次 props.orders 更改时,您编写 useEffect 钩子的方式都会 运行,因为您将该道具作为可选参数传递到数组中。您可以在 ReactJS 文档 here.

中阅读更多关于 useEffect 工作原理的信息

如果您希望您的 useEffect 挂钩仅在组件呈现时挂钩 运行 一次,您应该传递一个空数组:

useEffect(() => {
  setIsLoading(true);
  onFetchOrders('', 0);
}, []);

一旦开始抓取,就可以在另一个 useEffect 挂钩中将订单添加到道具中:

useEffect(() => {
  if (props.orders.length > 0) {
    setIsLoading(false);
    setOrders(props.orders)
  } else {
    setIsLoading(true);
  }

}, [props.orders])

useEffect 运行 每当组件中的任何 prop 发生变化时。为避免这种情况并在您的 useEffect 数组中仍然有订单,您可以使用 destructuring assignment syntax

const { orders } = props // where the magic happens

useEffect(() => {
  setIsLoading(true);
  onFetchOrders('', 0);

  if (orders.length > 0) {
    setOrders(orders)
  } else {
    setIsLoading(true);
  }

}, [orders])

此代码现在只会 运行 只要 orders 道具发生变化,而不是任何其他道具发生变化时。

此外,如果忘记提及,请查看 useEffect infinite loop problem。您可以将 useEffect 挂钩与 useCallback 挂钩结合使用以避免无限循环。

用 useCallback 挂钩将要传递给 useEffect 挂钩的函数包装起来。然后调用 useEffect 挂钩中的包装函数。这将避免 useEffect 中的无限循环。

const loadCustomers = useCallback(async (query: string, offset: number, limit?: number, filter?: {}) => {
    await props.fetchOrders('', 0);
    ...
}