【问题标题】:React: Why correct practice to receive api response via props?React:为什么正确的做法是通过 props 接收 api 响应?
【发布时间】:2019-09-02 09:05:37
【问题描述】:

我读到你的组件应该通过 props (mapStateToProps) 接收你的 API 响应,在它到达你的组件之前由 reducer 处理。

我的问题是那些道具没有被清除 - 搞砸了我的状态和渲染。

示例:我收到一条验证错误消息“validationErrorMsg”,我将状态设置为并呈现该状态。当用户触发另一个验证调用时,我会重置状态,但是当调用进行时,状态会再次填充包含旧的validationErrorMsg 的道具,该道具再次错误地更新状态。

我为解决这个问题所做的就是在我的 api 响应中调度 2 个事件。一个带有响应,另一个用于清除响应 - 这就是为什么要清除属性以使下一个正在运行的调用不会获取脏数据。

所以我的问题是,我做错了还是 API 响应不应该通过 props 系统来?

validate() {
  const { validateApiCall, formValues } = this.props;

  let serial = formValues.serial;

  this.setState({    
    validationError: undefined
  });

  validateApiCall({serialred});
}

下面的这个函数在按键、其他事件等上被调用。我刚刚重置了我的状态,但这将使用旧数据再次设置我的状态(通过 componentWillReceiveProps(nextProps) 是的,我知道不推荐使用)

function mapStateToProps( { upgrades} ) {
  let props = {
     propValidationError: (upgrades && upgrades.validationError ? upgrades.validationError : undefined)
  };
return props;

}

该死的,我又把旧东西拿回来了。

componentWillReceiveProps(nextProps) {
  if (nextProps.propValidationError) {
   this.setState({validationError: nextProps.tradeinValidationError});
  }
}

我目前对它的修复(感觉就像是因为糟糕的框架而被破解)。我通过调度另一个将清除道具的事件来清除道具。

try {
  const res = await axios.post(url, {formValues});
  dispatch({ type: FETCH_UPGRADES_TRADEIN_VALIDATE_DEVICE, payload: res.data });
  } catch (e) {
    const { data, status } = e.response;
    if (status >= 400 && status < 500) {
      dispatch({type: FETCH_UPGRADES_TRADEIN_VALIDATE_ERROR_RESPONSE, tradeinValidationError: data.message});
      dispatch({type: FETCH_UPGRADES_TRADEIN_VALIDATE_ERROR_RESPONSE_DONE, tradeinValidationError: data.message});
    }

【问题讨论】:

  • 在 yup 中验证,从 redux 接收一些 props,使用这个 props 设置 yup 验证

标签: reactjs redux


【解决方案1】:

当用户触发另一个验证调用时,您想要的行为是不再显示旧的validationErrorMsg,那么这意味着应该在用户触发另一个时从应用程序的状态中删除旧的错误消息验证调用。

状态存储的位置完全无关——组件的状态、Contex、Redux 等等。

如果您使用 Redux 并且存储错误消息的位置(完全可以的选择),那么您需要确保触发另一个验证调用的操作也删除旧的错误消息。

或者,也可以设置一个像“isFetching”这样的标志,将其设置为 true,并让组件在该标志为 true 时不显示错误消息,而是显示一些微调器。

无论如何,无论您将状态保存在哪里,所有这些相同的逻辑都需要发生。

【讨论】:

  • "那么这意味着旧的错误消息应该在用户触发另一个验证 cal 时从应用程序的状态中删除" 正如我所说的那样:this.setState({tradeinValidationError: undefined });但随后 mapStateToProps 再次触发,用旧数据污染(设置)我的状态(因为它不可能从道具中清除值)。 “或者,有一个像'isFetching'这样的标志”是的,这是另一种选择 - 所以基本上像我一样解决 - 问题是框架坏了吗?
  • @JacquesKoorts:这意味着您在 Redux 和组件的状态中具有相同的状态。不要那样做,选一个。
  • 我很高兴选择 Redux 的,但是如何清除 redux 中的属性?
  • @JacquesKoorts:最后一句话:不用 Redux 也是完全合法的。 Redux 试图解决的问题通常只出现在更大的应用程序中,并且引入它会导致额外的复杂性(如您所见)。因此,最好对所有内容都使用正常状态。
【解决方案2】:

API 响应应该来自 props。

如果您正在触发下一次验证,您可以重置存储/父组件中的值(不确定您如何传递这些道具)以不再传递相同的道具。

你能分享一些你如何处理的示例代码吗?

【讨论】:

  • 我确实重置了,但随后 mapStateToProps 将其全部恢复为旧的东西(您无法以可编程的方式清除单个道具)。附上示例代码
  • 您的组件从哪个来源获取道具?你需要在那里重置那些道具。所以如果你从父组件传递它,你应该在那里更新它。如果您从商店获得它,那么您应该在再次调用 api 之前重置商店。
  • 无父组件。我从调度事件(从减速器)中得到它。我不知道这些道具存储在哪里或如何清除它们。据我了解,您无法清除道具。
  • @JacquesKoorts:但是你可以派发一个动作,让 reducer 从 Redux 状态中删除该状态,以便从 props 中清除它们。
  • 就像@RemcoGerlich 提议的那样。
猜你喜欢
  • 1970-01-01
  • 2016-09-12
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多