【问题标题】:How to hide and show progress bar when fetching data from network?从网络获取数据时如何隐藏和显示进度条?
【发布时间】:2019-12-18 19:10:15
【问题描述】:

我在我的ReactNative 应用程序中使用Context Api 和Hooks

这是我从 api 获取博客数组的代码

const getBlogPosts = dispatch => {
  return async () => {
    try {
      const response = await jsonServer.get("/blogposts");
      dispatch({ type: "get_blogposts", payload: response.data });
    } catch (err) {
      dispatch({
        type: "get_blogposts",
        payload: "Something went wrong"
      });
    }
  };
};

const blogReducer = (state, action) => {
  switch (action.type) {
    case "get_blogposts":
      return action.payload;
     .....

在这里我的组件文件我正在做类似下面的事情

const IndexScreen = ({ navigation }) => {
  const { state, getBlogPosts } = useContext(Context);

  useEffect(() => {
    getBlogPosts();

  }, []);

  return (
    <View>
      <FlatList..../>
      {state.length === 0 ? <ProgressBar /> : null}

假设没有博客,那么即使在网络操作完成后,进度条也会一直显示,所以我无法编写上面的代码来显示和显示进度条 现在我尝试在用户调用 getBlogPosts 时触发多次调度,但这会将状态的值从布尔值更改为数组,然后再更改为布尔值。

有没有简单的方法来处理进度条的可见性?

【问题讨论】:

  • 你设置了长度吗??
  • @Idan 这是一个博文数组
  • 但是,从您的问题来看,尚不清楚什么是状态。我认为这部分将帮助人们/您回答您的问题。也许尝试记录打印并查看返回的内容。答案基于假设。

标签: reactjs react-native react-hooks react-context


【解决方案1】:

如果调度是get_blogposts_in_progress,你可以在调度中有一个新类型get_blogposts_in_progress,并在reducer中设置true/false,比如state.loading = true,当api调用成功或错误时调度state.loading = false .

const getBlogPosts = dispatch => {
  return async () => {
    dispatch({ type: "get_blogposts_in_progress" });
    try {
      const response = await jsonServer.get("/blogposts");
      dispatch({ type: "get_blogposts", payload: response.data });
    } catch (err) {
      dispatch({
        type: "get_blogposts",
        payload: "Something went wrong"
      });
    }
  };
};
const blogReducer = (state, action) => {
  switch (action.type) {
    case "get_blogposts_in_progress":
      return { ...state, ...{ loading: true } };
    case "get_blogposts":
      return { ...action.payload, ...{ loading: false } };
     .....

还有组件文件。

const IndexScreen = ({ navigation }) => {
  const { state, getBlogPosts } = useContext(Context);

  useEffect(() => {
    getBlogPosts();

  }, []);

  return (
    <View>
      <FlatList..../>
      {state.loading ? <ProgressBar /> : null}

【讨论】:

  • 行 return { ...action.payload, ...{ loading: false } };由于您已将加载参数添加到数组中,因此不会呈现我的列表
  • 试试{ ...state, ...action.payload, ...{ loading: false } };
【解决方案2】:

由于您的博客数组可以为空,加载后您的博客数组可能相同。您必须存储一个布尔值,指示加载已在您的状态下完成。

获取数据后,只需将此值设置为 false

const IndexScreen = ({ navigation }) => {
  const { state, getBlogPosts } = useContext(Context);
  const [loading, setLoading] = useState(true);

  useEffect(async () => {
    await getBlogPosts();
    setLoading(false)
  }, []);

  return (
    <View>
      <FlatList..../>
      {loading && <ProgressBar />}

您还必须使您的效果async 能够使用await

我还使用内联 if (&amp;&amp;) 来渲染加载组件。

【讨论】:

  • 其实我也想过这个,但我不想用这种方式,而是使用Reducer。谢谢你的回答
  • 这给我带来了问题,我不得不将 async 函数包装在一个非异步函数中:useEffect( ()=&gt;{ (async ()=&gt;{ //do stuff } )() })
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多