【问题标题】:Access Relay state without passing down props在不传递 props 的情况下访问 Relay 状态
【发布时间】:2022-01-24 16:26:14
【问题描述】:
我现在正在学习 Relay,我想知道是否有一种无需传递道具即可访问状态的方法。我认为 Relay 使用了 React Context,但是,在所有示例中,它们似乎都在使用 props 来传递状态,而不是直接访问 Context 存储。是否可以通过上下文访问状态?如果是这样,这是否被认为是不好的做法?
我担心我会开始有很多道具被传递给组件。此外,在我的应用程序中,很难将 props 传递给某些组件。
【问题讨论】:
标签:
javascript
reactjs
react-context
relay
react-relay
【解决方案1】:
使用上下文、redux 或其他类型的外部存储传递 Relay 状态是一种不好的做法。该库的核心功能之一是确保所有需要数据的组件都获得该数据,而不是其他数据。 This is one of the reasons Relay uses a compiler.
借助 Relay,开发人员使用一种称为 GraphQL 的声明性语言来指定每个组件需要哪些数据,而不是如何获取这些数据。
[编译器] 允许独立地推理组件,使大类错误成为不可能
子组件应该使用fragments。例如:
// User.tsx
interface UserProps {
initialQueryRef: PreloadedQuery<UserQuery>
}
export default function User({ initialQueryRef }: UserProps) {
const { user } = usePreloadedQuery(
graphql`
query UserQuery($uid: String!) {
user(uid: $uid) {
uid
...Avatar_fragment
...Biography_fragment
# ...
}
}
`,
initialQueryRef
)
return (
<div>
<Avatar user={user} />
<Biography user={user} />
{/* ... */}
</div>
)
}
// Biography.tsx
interface BiographyProps {
user: Biography_fragment$key // compiler generated type
}
export default function Biography({ user }: BiographyProps) {
const { shortBio, longBio } = useFragment(
graphql`
fragment Biography_fragment on User {
shortBio
longBio
}
`,
user
)
// ...
}
每当片段数据由于突变、订阅等原因发生变化时,Relay 将负责更新使用片段的组件。您永远不必考虑以编程方式管理它们的状态。