使用 lodash/fp 的 get 方法有什么好处吗?



一段时间以来,这一直是我团队中几个人之间的争论点。

在我们的应用程序中,我们使用 apollo graphql 对我们的 API 进行异步查询/更改。

也就是说,在过去,已经有一些决定使用lodash/fpget来设置这样的变量:

import { graphql } from '@apollo/hoc';
import { get } from 'lodash/fp';
const Component = (props) => {
const data = get('data.user', 'props');

return (
<>
{data.member.name}
<OtherComponent data={get('data.member.whatever.data', 'props')} />
</>
)
}
export default compose(
graphql(MY_QUERY, {
options: { variables: { id: 'abc123dorime' } }
}), // async data
)(Component)

根据我继承此应用程序的经验,这很容易出错。有时它会导致错误,有时不会;基本上是一种竞争条件。我的理论是:如果 react 渲染速度快于解析速度,它会使应用程序崩溃。未处理加载状态,也没有错误处理。但是,我对此不是 100% 确定,因为我真的不知道get如何完全在引擎盖下工作。此特定示例的错误是此处undefineduser有时。在我们开发时,我通常会很好,但是我们的用户在使用get的页面上报告了错误。有时!!!

但是,我决心放弃使用get来解决异步数据。我的方法是移动到 apollo 的钩子,并实际使用它提供的loading状态在渲染之前解析异步数据:

import { useQuery, useMutation } from '@apollo/react-hooks';
const Component = () => {
const { data, loading, error } = useQuery(MY_QUERY, {
variables: { id: '123abcdorime' },
});
const [ myMutation, { loading: mutationLoading } ] = useMutation(MY_MUTATION, {
variables: { id: '123', input: { name: 'whatever' } },
onCompleted: () => doSomething(),
onError: (err) => handleError(err),
});
return (
<>
{loading && <LoadingCircle />}
{!loading && (
<>
{error && <ErrorHandler error={error} />}
{!error && <>data.user.member.name</>}
</>
)}
</>
);
}
export default Component;

这样,它可以在逻辑上考虑loading状态并正确解析,并在不使用的情况下正确呈现get,重构为后一种模式倾向于解决getgetOr倾向于在我们的生产应用程序中给我们带来的异步问题。

有些观点是,lodash/fpget提供了空检查,将编码防御性地付诸实践,但后者在逻辑上不是也在使用错误处理/加载状态进行防御性编码吗?

我想我最大的问题是:

  • getgetOr什么时候是一个好的用例?
  • 。它们对于处理异步数据有用吗

这纯粹是出于好奇。如前所述,这是我和我的团队之间的一个巨大争论点,我们应用程序中的大多数问题都源于get和异步数据的使用。我只想知道我是否误解了什么,或者我/我们是否滥用了get/getOr.

get根本不与异步相关...您应该始终保护任何data属性/字段访问(分配给其他常量/变量,作为 prop 传递(。

const data = get('data.user', 'props'(;

。这是一点保护 - "正常"const data = props.data.user;如果不加载data会失败("著名"反应错误"Cannot read property 'XXXXXXX' of undefined"(

{data.member.name}

。应该受到保护,即通过{props.data && data.member.name}

。这不会失败,但可能会导致意外的data(undefined(作为prop传递,而不是预期/获取的值。

没有<Loading/>就足够了if(!props.data) return null;(当然在呈现适当的内容之前(

return (
<>
{loading && <LoadingCircle />}
{!loading && (

你可以简单地

// '!data' is equal to 'loading' in this case
if(loading || mutationLoading) return <LoadingCircle />
if(error) return <ErrorHandler error={error} />
return (
<>data.user.member.name</>
)

最新更新