在Redux操作中导航React Native。

huangapple go评论53阅读模式
英文:

Navigate in react native in redux action

问题

以下是您要翻译的内容:

"我有一个注册表单,提交后,只有在操作文件中的请求成功时,我才想导航到其他屏幕,而不是在组件本身。

我将navigation作为参数从我的组件传递给函数,但导航没有发生。

对于这个问题有任何建议吗?

// Action.js
export const registerUser = (formData, navigation) => async dispatch => {
  try {
    const response = await axios.post(`${config.END_POINT}/users`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })

    await AsyncStorage.setItem('token', response.data.token)

    dispatch({ type: 'auth/setToken' })

    loadUser(navigation)
  } catch (error) {
    console.error(error.message)
  }
}
export const loadUser = (navigation) => async dispatch => {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`)

    dispatch({
      type: 'auth/setUser',
      payload: response.data
    })

    navigation.navigate('Home')
  } catch (error) {
    console.error(error.message)
  }
}

在component.js中填写表单后

dispatch(registerUser(formData, navigation))
```"

<details>
<summary>英文:</summary>

I have a registration form that after submission of which I want to navigate to other screen only if the request succeeds in the action file not in Component itself.

I&#39;m sending `navigation` as an argument to the function from my component but the navigation is not happening.

Any suggestions about this issue?

```javascript
// Action.js
export const registerUser = (formData, navigation) =&gt; async dispatch =&gt; {
  try {
    const response = await axios.post(`${config.END_POINT}/users`, formData, {
      headers: {
        &#39;Content-Type&#39;: &#39;multipart/form-data&#39;
      }
    })

    await AsyncStorage.setItem(&#39;token&#39;, response.data.token)

    dispatch({ type: &#39;auth/setToken&#39; })

    loadUser(navigation)
  } catch (error) {
    console.error(error.message)
  }
}
export const loadUser = (navigation) =&gt; async dispatch =&gt; {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`)

    dispatch({
      type: &#39;auth/setUser&#39;,
      payload: response.data
    })

    navigation.navigate(&#39;Home&#39;)
  } catch (error) {
    console.error(error.message)
  }
}

In component.js after filling form

dispatch(registerUser(formData, navigation))

答案1

得分: 1

loadUser 似乎是另一个异步操作创建函数。loadUser 是一个接受 navigation 参数并返回另一个函数的函数,为了执行该函数体并生效导航操作,还需要调用返回的函数。registerUser 动作调用了 loadUser(navigation),但然后没有调用返回的函数。

换句话说,loadUser(navigation) 返回以下内容:

async dispatch => {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`);

    dispatch({
      type: 'auth/setUser',
      payload: response.data
    });

    navigation.navigate('Home');
  } catch (error) {
    console.error(error.message);
  }
};

这个函数从未被调用。

你应该分发这个 loadUser 动作,以便 thunk/异步中间件可以调用该函数,并再次将 dispatch 传递给它。

示例:

export const registerUser = (formData, navigation) => async dispatch => {
  try {
    const response = await axios.post(
      `${config.END_POINT}/users`,
      formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    );

    await AsyncStorage.setItem('token', response.data.token);

    dispatch({ type: 'auth/setToken' });

    dispatch(loadUser(navigation)); // <-- 分发动作!
  } catch (error) {
    console.error(error.message);
  }
};
英文:

loadUser appears to be another asynchronous action creator. loadUser is a function that takes a navigation argument and returns another function that needs to also be called in order for that function body to be executed and the navigation action effected. The registerUser action calls loadUser(navigation) but then never calls the returned function.

In other words, loadUser(navigation) returns the following

async dispatch =&gt; {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`);

    dispatch({
      type: &#39;auth/setUser&#39;,
      payload: response.data
    });

    navigation.navigate(&#39;Home&#39;);
  } catch (error) {
    console.error(error.message);
  }
};

This function is never called.

You should dispatch this loadUser action so the thunk/asynchronous middleware can call the function and again pass dispatch to it.

Example:

export const registerUser = (formData, navigation) =&gt; async dispatch =&gt; {
  try {
    const response = await axios.post(
      `${config.END_POINT}/users`,
      formData, {
        headers: {
          &#39;Content-Type&#39;: &#39;multipart/form-data&#39;
        }
      }
    );

    await AsyncStorage.setItem(&#39;token&#39;, response.data.token);

    dispatch({ type: &#39;auth/setToken&#39; });

    dispatch(loadUser(navigation)); // &lt;-- dispatch action!
  } catch (error) {
    console.error(error.message);
  }
};

答案2

得分: 0

你正在在成功注册后,从registerUser操作中调用loadUser函数。然而,loadUser函数是异步的,意味着它不会立即返回一个值。因此,在loadUser之后的导航调用不会等待loadUser函数完成后再进行导航。

为了确保导航仅在loadUser成功完成后发生,你可以修改registerUser操作,使其返回一个在loadUser完成时解析的promise。以下是如何修改registerUser操作:

export const registerUser = (formData, navigation) => async dispatch => {
  try {
    const response = await axios.post(`${config.END_POINT}/users`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })

    await AsyncStorage.setItem('token', response.data.token)

    dispatch({ type: 'auth/setToken' })

    await dispatch(loadUser(navigation)) // 等待loadUser完成

  } catch (error) {
    console.error(error.message)
  }
}

通过等待对loadUser的调用,导航仅会在loadUser成功完成后发生。还要确保从loadUser函数中返回loadUser调用,以便可以在registerUser操作中等待。

export const loadUser = (navigation) => async dispatch => {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`)

    dispatch({
      type: 'auth/setUser',
      payload: response.data
    })

    navigation.navigate('Home')

    return true // 返回一个值以指示成功

  } catch (error) {
    console.error(error.message)

    return false // 返回一个值以指示失败
  }
}

通过这些更改,registerUser操作现在应该返回一个promise,在loadUser函数完成时解析,并且导航仅在loadUser函数成功完成后发生。

英文:

you are calling the loadUser function from the registerUser action after a successful registration. However, the loadUser function is asynchronous, meaning that it does not immediately return a value. Therefore, the navigation call after loadUser will not wait for the loadUser function to complete before navigating.

To make sure that the navigation only happens after loadUser has completed successfully, you can modify the registerUser action to return a promise that resolves when loadUser is done. Here's how you can modify the registerUser action:

export const registerUser = (formData, navigation) =&gt; async dispatch =&gt; {
  try {
    const response = await axios.post(`${config.END_POINT}/users`, formData, {
      headers: {
        &#39;Content-Type&#39;: &#39;multipart/form-data&#39;
      }
    })

    await AsyncStorage.setItem(&#39;token&#39;, response.data.token)

    dispatch({ type: &#39;auth/setToken&#39; })

    await dispatch(loadUser(navigation)) // Wait for loadUser to complete

  } catch (error) {
    console.error(error.message)
  }
}

By await-ing the dispatch call to loadUser, the navigation will only happen after loadUser has completed successfully. Also, make sure that you return the loadUser call from the loadUser function so that it can be await-ed in the registerUser action.

export const loadUser = (navigation) =&gt; async dispatch =&gt; {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`)

    dispatch({
      type: &#39;auth/setUser&#39;,
      payload: response.data
    })

    navigation.navigate(&#39;Home&#39;)

    return true // Return a value to indicate success

  } catch (error) {
    console.error(error.message)

    return false // Return a value to indicate failure
  }
}

With these changes, the registerUser action should now return a promise that resolves when the loadUser function completes, and the navigation should only happen after the loadUser function has completed successfully.

huangapple
  • 本文由 发表于 2023年5月17日 23:53:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273986.html
  • javascript
  • react-native
  • react-native-navigation
  • react-redux
  • reactjs