Reactjs 使用React/Relay/Typescript跨片段重用组件的最佳实践是什么?

Reactjs 使用React/Relay/Typescript跨片段重用组件的最佳实践是什么?,reactjs,typescript,relay,Reactjs,Typescript,Relay,我正在用React、Relay(实验)和Typescript制作一个web应用程序,在不同片段中重复使用具有类似数据/道具的组件时遇到了一些问题 假设我有以下中继查询和主要应用程序组件: const query = graphql` query AppQuery { currentUser { ...HomePage_currentUser ...ProfilePage_currentUser } } `; export default func

我正在用React、Relay(实验)和Typescript制作一个web应用程序,在不同片段中重复使用具有类似数据/道具的组件时遇到了一些问题

假设我有以下中继查询和主要应用程序组件:

const query = graphql`
  query AppQuery {
    currentUser {
      ...HomePage_currentUser
      ...ProfilePage_currentUser
    }
  }
`;

export default function App(): JSX.Element {
  const appData = useLazyLoadQuery<AppQuery>(query, {});
 
 return (
   <>
    <HomePage currentUser={appData.currentUser}>
    <ProfilePage currentUser={appData.currentUser}>
   </>
 );
}
我的主要问题是关于
ProfileIcon
组件中的
currentUser
道具的类型。似乎没有干净的方法可以将组件重新用于
ProfilePage\u currentUser
类型和
HomePage\u currentUser
类型,尽管所请求的数据非常相似,并且为了该组件,它显然是兼容的

除了这样的事情,还有什么推荐的处理方法吗

interface ProfileIconProps {
  currentUser: Omit<ProfilePage_currentUser, ' $refType'>
}
interface ProfileIconProps{
当前用户:省略
}

在中继中,提取数据并将其作为道具手动传递给组件不是一种好的做法。相反,您应该在
ProfileIcon
组件上有一个片段,并让Relay负责将相同的数据传递给您的组件

因此,您需要在ProfileIcon组件中创建一个片段,并查询
profileImageUrl
,然后在
HomePage\u currentUser
ProfilePage\u currentUser
片段中添加此片段,relay将为您处理其余部分

interface ProfileIconProps {
  currentUser: ProfileIcon_currentUser$key | null;
}

const currentUserFragment = graphql`
  fragment ProfileIcon_currentUser on User {
    profileImageUrl
  }
`;


export default function ProfileIcon(props: ProfileIconProps): JSX.Element {
  const currentUser = useFragment(currentUserFragment, props.currentUser);

  return (
    <div>
     <img src={props.currentUser.profileImageUrl} />
    </div>
  )
}
`)

在ProfilePage组件中添加
ProfileIcon\u currentUser
fragment

const currentUserFragment = graphql`
 fragment HomePage_currentUser on User {
    id
    items {
      id
      name
    }
    ...ProfileIcon_currentUser
 }
 const currentUserFragment = graphql`
  fragment ProfilePage_currentUser on User {
    id
    lastLoggedInTimestamp
    ...ProfileIcon_currentUser
  }
`;
使用此模式的一个优点是,如果您在其他地方(即使不在同一个react节点树层次结构中)的用户上发生了变异,那么假设您
更改
profileImageUrl
,则ProfileIcon将自动接收新的
profileImageUrl
,而无需传递profileImageUrl的新值。事实上,中继存储将使用变异有效负载上的新值进行更新,一旦存储中有新的更新,它将把该数据传递给使用该数据的任何组件。

在中继中提取数据并将其作为道具手动传递给组件不是一个好的做法。相反,您应该在
ProfileIcon
组件上有一个片段,并让Relay负责将相同的数据传递给您的组件

因此,您需要在ProfileIcon组件中创建一个片段,并查询
profileImageUrl
,然后在
HomePage\u currentUser
ProfilePage\u currentUser
片段中添加此片段,relay将为您处理其余部分

interface ProfileIconProps {
  currentUser: ProfileIcon_currentUser$key | null;
}

const currentUserFragment = graphql`
  fragment ProfileIcon_currentUser on User {
    profileImageUrl
  }
`;


export default function ProfileIcon(props: ProfileIconProps): JSX.Element {
  const currentUser = useFragment(currentUserFragment, props.currentUser);

  return (
    <div>
     <img src={props.currentUser.profileImageUrl} />
    </div>
  )
}
`)

在ProfilePage组件中添加
ProfileIcon\u currentUser
fragment

const currentUserFragment = graphql`
 fragment HomePage_currentUser on User {
    id
    items {
      id
      name
    }
    ...ProfileIcon_currentUser
 }
 const currentUserFragment = graphql`
  fragment ProfilePage_currentUser on User {
    id
    lastLoggedInTimestamp
    ...ProfileIcon_currentUser
  }
`;
使用此模式的一个优点是,如果您在其他地方(即使不在同一个react节点树层次结构中)的用户上发生了变异,那么假设您 更改
profileImageUrl
,则ProfileIcon将自动接收新的
profileImageUrl
,而无需传递profileImageUrl的新值。事实上,中继存储将使用变异有效负载上的新值进行更新,一旦存储中有新的更新,它将把该数据传递给使用该数据的任何组件