当前位置: 首页 > 面试题库 >

反应useReducer异步数据获取

厉高逸
2023-03-14
问题内容

我正在尝试使用新的react useReducer API来获取一些数据,并停留在需要异步获取的阶段。我只是不知道如何:/

如何将数据获取放置在switch语句中,或者这不是应该完成的方式?

import React from 'react'

const ProfileContext = React.createContext()

const initialState = {
  data: false
}

let reducer = async (state, action) => {
  switch (action.type) {
    case 'unload':
      return initialState
    case 'reload':
      return { data: reloadProfile() } //how to do it???
  }
}


const reloadProfile = async () => {
  try {
    let profileData = await fetch('/profile')
    profileData = await profileData.json()

    return profileData
  } catch (error) {
    console.log(error)
  }
}

function ProfileContextProvider(props) {
  let [profile, profileR] = React.useReducer(reducer, initialState)

  return (
    <ProfileContext.Provider value={{ profile, profileR }}>
      {props.children}
    </ProfileContext.Provider>
  )
}

export { ProfileContext, ProfileContextProvider }

我试图这样做,但它不能与异步一起工作;(

let reducer = async (state, action) => {
  switch (action.type) {
    case 'unload':
      return initialState
    case 'reload': {
      return await { data: 2 }
    }
  }
}

问题答案:

这是一个有趣的案例,useReducer示例没有涉及。我认为减速器不是异步加载的正确位置。来自Redux的心态,您通常会将数据加载到其他位置,例如以thunk,可观察(例如redux-
observable)或仅在生命周期事件中加载componentDidMount。对于新版本,useReducer我们可以使用的componentDidMount方法useEffect。您的效果可能类似于以下内容:

function ProfileContextProvider(props) {
  let [profile, profileR] = React.useReducer(reducer, initialState);

  useEffect(() => {
    reloadProfile().then((profileData) => {
      profileR({
        type: "profileReady",
        payload: profileData
      });
    });
  }, []); // The empty array causes this effect to only run on mount

  return (
    <ProfileContext.Provider value={{ profile, profileR }}>
      {props.children}
    </ProfileContext.Provider>
  );
}

另外,这里的工作示例:https :
//codesandbox.io/s/r4ml2x864m。

如果您需要将prop或状态传递给reloadProfile函数,可以通过将第二个参数调整为useEffect(示例中的空数组),使其仅在需要时运行。您可能需要检查先前的值或实现某种缓存,以避免在不必要时进行提取。

如果您希望能够从子组件中重新加载,可以通过以下两种方法进行。第一种选择是将回调传递给子组件,该子组件将触发分派。这可以通过上下文提供程序或组件属性完成。由于您已经在使用上下文提供程序,因此下面是该方法的示例:

function ProfileContextProvider(props) {
  let [profile, profileR] = React.useReducer(reducer, initialState);

  const onReloadNeeded = useCallback(async () => {
    const profileData = await reloadProfile();
    profileR({
      type: "profileReady",
      payload: profileData
    });
  }, []); // The empty array causes this callback to only be created once per component instance

  useEffect(() => {
    onReloadNeeded();
  }, []); // The empty array causes this effect to only run on mount

  return (
    <ProfileContext.Provider value={{ onReloadNeeded, profile }}>
      {props.children}
    </ProfileContext.Provider>
  );
}

如果您 确实
想使用分派函数而不是显式回调,则可以通过将分派包装在一个高阶函数中进行处理,该函数处理Redux世界中中间件已经处理过的特殊动作。这是一个例子。请注意profileR,我们传递的自定义变量类似于中间件,而不是直接传递给上下文提供程序,它拦截了reducer无关的特殊操作。

function ProfileContextProvider(props) {
  let [profile, profileR] = React.useReducer(reducer, initialState);

  const customDispatch= useCallback(async (action) => {
    switch (action.type) {
      case "reload": {
        const profileData = await reloadProfile();
        profileR({
          type: "profileReady",
          payload: profileData
        });
        break;
      }
      default:
        // Not a special case, dispatch the action
        profileR(action);
    }
  }, []); // The empty array causes this callback to only be created once per component instance

  return (
    <ProfileContext.Provider value={{ profile, profileR: customDispatch }}>
      {props.children}
    </ProfileContext.Provider>
  );
}


 类似资料:
  • 我正在尝试使用新的reactuseReucker API获取一些数据,并停留在我需要异步获取它的阶段。我只是不知道如何:/ 如何将数据提取放在switch语句中,还是不应该这样做? 我试图这样做,但它不与异步工作;

  • 我对状态同步有问题。当我点击编辑器的外部(想要关闭它),我想把实际的文本传回给父节点(函数)。但是当我在之外单击时,状态似乎总是落后一步。(例如:如果编辑器内部有,我键入,,我键入,等等)。 如果我在编辑器外单击,将出现的实际状态,如何实现这一点?

  • Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。 使用Nuxt.js的异步数据 了解如何使用Nuxt.js管理异步数据。 由VueSchool制作视频课程,用于支持Nuxt.js开发。 asyncData 方法 asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。

  • 我试图创建一个从服务器获取数据的函数,它工作了。但我不确定这是不是正确的方法? 我不确定是调用fetchData函数的地方。我在里面做那个有用吗?对地方?而且,这个电话只会发生一次?因为我用[]? 一般来说,你会怎么做这样的事情?

  • 默认情况下,createStore() 所创建的 Redux store 没有使用 middleware,所以只支持 同步数据流。 你可以使用 applyMiddleware() 来增强 createStore()。虽然这不是必须的,但是它可以帮助你用简便的方式来描述异步的 action。 像 redux-thunk 或 redux-promise 这样支持异步的 middleware 都包装了

  • Nuxt.js 扩展了 Vue.js,增加了一个叫asyncData的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。 asyncData 方法 asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。 在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用asyncData方法来获取数据,Nuxt.js 会将async