Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
62 views
in Technique[技术] by (71.8m points)

javascript - How to pass a promise to a component while using it in useEffect (React)?

I have a react component which fetches users from a server:

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

As you can see I render a InnerComponent that receives data (a promise of users) as a prop.
This obviously calls the function getUsers which triggers another network request.

My question is how can I call getUsers only once (must be called in the useEffect hook like i did since i rely on dependecy array), and use the promise returned as the data prop in InnerComponent?

Edit: InnerComponent expects a promise to subscribe to so it can display a different view depending on the promise state (pending, fullfilled, rejected)

Edit: Implementation of InnerComponent (Pretty much a component that displays an error or loading views based on the promise state)

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}
    </>
  )
}
question from:https://stackoverflow.com/questions/65859857/how-to-pass-a-promise-to-a-component-while-using-it-in-useeffect-react

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

you could pass some other props for update promise status.Check my updated answer

Updated with promise state activity

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...