【问题标题】:Redux constantly updatingRedux 不断更新
【发布时间】:2020-08-31 10:02:42
【问题描述】:

我正在使用 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 挂钩会不断重新呈现,因为订单数组中似乎有更新。

【问题讨论】:

  • 也许onFetchOrders 会更新您的订单数组?
  • 为什么要使用内部订单变量和props.orders?

标签: reactjs react-native redux redux-thunk


【解决方案1】:

您编写useEffect 挂钩的方式将在每次props.orders 更改时运行,因为您将数组中的该道具作为可选参数传递。您可以在 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])

【讨论】:

    【解决方案2】:

    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);
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 2020-08-01
      相关资源
      最近更新 更多