首页 > 解决方案 > 如何在 useEffect (React) 中使用组件时向组件传递承诺?

问题描述

我有一个从服务器获取用户的反应组件:

export function UsersTable() {
  const [users, setUsers] = useState([])
  const [userFilters, setUserFilters] = useState(...)

  useEffect(() => {
    getUsers(userFilters).then(usersData => setUsers(usersData.data))
  }, [userFilters])

  return (
    <InnerComponent data={getUsers(userFilters)} />
    ...
  )
}

正如你所看到的,我渲染了一个InnerComponent接收data(用户的承诺)作为道具。
这显然调用了getUsers触发另一个网络请求的函数。

我的问题是我怎样才能getUsers只调用一次(必须useEffect像我一样在挂钩中调用,因为我依赖于依赖数组),并使用返回的承诺作为data道具InnerComponent

编辑:InnerComponent期望订阅一个承诺,因此它可以根据承诺状态显示不同的视图(待处理、已完成、已拒绝)

编辑:InnerComponent 的实现(几乎是一个根据承诺状态显示错误或加载视图的组件)

type LoadableProps<T> = {
  data: Promise<T>,
  loading: JSX.Element,
  error: JSX.Element,
  children?: JSX.Element
}

enum LoadableState {
  LOADING,
  DATA_FETCHED,
  ERROR
}

export function InnerComponent<T>(props: LoadableProps<T>) {
  const [loadableState, setLoadableState] = useState(LoadableState.LOADING)

  useEffect(() => {
    props.data.then(result => {
     setLoadableState(LoadableState.DATA_FETCHED)
    }, error => {
      setLoadableState(LoadableState.ERROR)
    }).catch(error => {
      setLoadableState(LoadableState.ERROR)
    })
  }, [])

  return (
    <>
      {loadableState === LoadableState.DATA_FETCHED ? props.children : null}
      {loadableState === LoadableState.LOADING ? props.loading : null}
      {loadableState === LoadableState.ERROR ? props.error : null}
    </>
  )
}

标签: javascriptreactjspromise

解决方案


您可以通过其他一些道具来更新承诺状态。检查我更新的答案

更新了承诺状态活动

export function UsersTable() {
  const [users, setUsers] = useState([]);
  const [promiseState, setPromiseState] = useState(null);
  const [userFilters, setUserFilters] = useState(...)

  useEffect(() => {
    setPromiseState('pending')
    getUsers(userFilters).then((usersData) =>{ 
      setPromiseState('fullfilled')
      setUsers(usersData.data);
    }).catch((err)=>{setPromiseState('rejected')})
  }, [userFilters])

  return (
    <InnerComponent data={users} promiseState={promiseState} />
    ...
  )
}

推荐阅读