【问题标题】:Leverage local state and avoid fetching data when data is already available?利用本地状态并避免在数据已经可用时获取数据?
【发布时间】:2020-01-13 19:01:52
【问题描述】:

我目前有几个 api 获取数据,这反过来又需要来自先前 api 的数据,以便后续 api 获取必要的数据,具体取决于交互和路由。目前,我已经将所有这些联系在一起,并且与我的减速器和动作配合得很好。但是,我想知道如何根据本地状态是否已经可用有条件地获取数据?

我的理想解决方案是在用户第一次加载数据后利用本地状态,而不必继续在其初始实例上获取数据。我见过很多从 api 中提取数据的例子,但是没有一个例子可以说明出于性能原因使用本地数据(已经获取),而不是每次渲染组件/页面时都必须调用 api。

解决这种情况的最佳方法是什么?

这是我目前所拥有的,想知道这是否是一个好方法?

idea.sagas.js

function shouldFetchIdeas() {
  const state = store.getState();
  if (!state.idea.ideas) {
    return true;
  } else {
    return false;
  }
}

export function* fetchIdeas({ payload: organizationId }) {
  if (shouldFetchIdeas()) {
    try {
      const fetchApi = yield axios(
        `https://api.getconflux.com/api/v1/public/${organizationId}/ideas`
      );
      yield put(fetchIdeasSuccess(fetchApi.data.rows));
    } catch (error) {
      yield put(fetchIdeasFailure(error.message));
    }
  }
}


export function* onFetchIdeasStart() {
  yield takeLatest(IdeasActionTypes.FETCH_IDEAS_START, fetchIdeas);
}

export function* ideaSagas() {
  yield all([call(onFetchIdeasStart)]);
}

这目前有效,但感觉很脏。我有大约 3-4 个 api 调用,我上面展示的就是一个例子。是否有替代方法或正确方法来利用本地状态而不必每次都获取数据?

无论如何,很高兴听到您的想法,或者是否有更好的管理方法,或者您是否可以指导我找到任何解决方案或任何示例。

提前致谢!

【问题讨论】:

  • 此问题可能已关闭,因为它没有明确的问题陈述。您也没有提供有关问题规模的任何背景信息,以及为什么这对您来说是个问题
  • github.com/rt2zz/redux-persist 可能会帮助你
  • @imjared 我已经内置了持久化,但无论如何我都会继续从 api 获取数据。当您已经获取它之后就不需要了。例如,如果我进入一条新路线然后返回,它将重新获取数据,而不是使用我们已经加载的数据。我希望在第一次初始获取后只使用本地状态,然后为不同的交互操作状态。
  • @Sananes - 你为什么要再次获取想法?如果您在开始时获取它们,您可以使用redux 来管理它们而无需再次获取它们
  • @jank 很抱歉不清楚。这正是我所指的。不必再次获取数据。获取一次,然后只使用全局应用程序状态。但我的问题是每次我更改路线并访问显示它获取的(已经获取的数据)的页面与使用全局应用程序状态中可用的内容时。我只是想知道是否有特定的最佳实践方式来做到这一点。到目前为止,我所做的只是一个查看数据是否已经可用的函数,如果是,则不要获取。

标签: reactjs redux react-redux local-storage redux-saga


【解决方案1】:

您应该使用本地状态而不是再次获取数据以更新您的本地状态并因此更新视图。这是 redux 等框架试图实现的目标之一。

为此,请使用一个容器组件来获取所有必要的数据并将其传递给每个路由中的子组件:

class App extends Component {
    componentDidMount() {
        this.props.actions.getTrailers();
        this.props.actions.getCharacters();
        this.props.actions.getFavorites();
    }

    render() {  
        return (
            <Switch>
                <Route path="/characters">
                    <Characters characters={characters} />
                </Route>
                <Route path="/favorites">
                    <Favorites favorites={favorites} />
                </Route>
                <Route path="/trailers">
                    <Trailers trailers={trailers} />
                </Route>
            </Switch>
        }
    }
}

在每个子组件内部,您可以使用redux 选择器访问其他组件的数据。例如&lt;Trailers /&gt; 可以通过选择器访问favoritescharacters,或者使用自己的props 来获取他的专用数据(即:trailers)。

这种做法可以减少多余的 API 调用,并帮助您在开发工具中保持网络选项卡的整洁。此外,由于您已经预取了子组件的数据,这将有助于更快地呈现子组件。

此外,想想如何在 CRUD 操作上管理相同的做法。每个操作还需要 API 调用。您可以在 reducer 中处理它们,并避免为每个操作再次获取数据。这样做将使您的应用保持响应。

除非你点击刷新,否则 Redux 会保持你的状态,那么你需要 redux-persist

希望它有所帮助,我可能会更新此答案,因为它可能需要进一步澄清。

【讨论】:

  • 这完全有道理!非常感谢您的解释。真的很感激我的男人!
  • 这是另一个问题。我有两条路线。 ideasidea 详细信息页面的概述。个人想法需要单独获取,概述本身不需要,因为它已经被获取。问题是,如果我直接访问idea 个人详细信息页面,那么它仍然想获取ideas 作为其容器的一部分。我该如何防止这种情况发生? ``` ideas overviewIdea detail // 这个特定的路由不需要获取想法数据 ```
  • @Sananes - idea 不是ideas 的一部分吗?我问这个是为了了解来自您的端点的数据的结构,并了解您是否有理由单独获取idea
  • 不幸的是,这就是 api 的结构。单个想法帖子包含更多数据,因此它是一个单独的提取。我们有ideas,这是一个公司所有想法的列表,然后我们有单独的idea 项目,它提供了更多细节。希望,谢谢更有意义!感谢所有这些@jank
  • @Sananes - 所以有两个组件应该在它们的componentDidMount() 中获取不同的数据:1.)&lt;Ideas /&gt; - 应该获取初始的ideas(用于概述)。 2.)&lt;Idea id={idea.id} /&gt; - 应该获取具有给定 id 作为道具的idea。路由不应该导致容器组件的重新渲染,你能验证这个流程吗?注意:如果您从另一个组件重定向到 &lt;idea /&gt;,则会导致该组件重新渲染。
猜你喜欢
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多