Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add better server component support #47945

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

EvanBacon
Copy link
Contributor

Summary:

  • Move the top-level use client directive down to specific modules.
  • This enables support for Platform.OS, StyleSheet.create, processColor, in react-server environments.
  • Converted UnimplementedView to a function component since class components are not supported in RSC.
  • Dimensions module has shims for StyleSheet/PixelRatio that are similar to react-native-web. We use typeof window === 'undefined' checks, which work on native since the react-native initial polyfill enforces that window is defined.

Changelog:

[ANDROID] [ADDED] - Added Platform.OS and StyleSheet.create support for react-server environments.
[IOS] [ADDED] - Added Platform.OS and StyleSheet.create support for react-server environments.

Test Plan:

  • Ran this patch in an Expo SDK 52 project with server components enabled.
"use server";

import {
  Image,
  processColor,
  ScrollView,
  StyleSheet,
  Text,
  View,
  Modal,
  Platform,
  DrawerLayoutAndroid
} from "react-native";

export async function renderThing() {
  return (
    <View>
    <DrawerLayoutAndroid />
    <View style={styles.container}>
      <Text>Thing {JSON.stringify(processColor("blue"))} {Platform.OS}</Text>
      <Image source={require("@/assets/images/partial-react-logo.png")} />
      <ScrollView />
    </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
    borderWidth: StyleSheet.hairlineWidth,
  },
});

with execution:

<React.Suspense fallback={null}>{renderThing()}</React.Suspense>

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Nov 26, 2024
@kassens
Copy link
Member

kassens commented Nov 26, 2024

Just regarding the Dimensions mock: I don't think other globals have mocks on the web either, right? Not a RSC expert, but returning random values doesn't seem great here as if those values are used on the server, it'll not match the client results.

@EvanBacon
Copy link
Contributor Author

@kassens react-native-web / react-strict-dom are reasonable examples from the Meta team of server compatibility for client APIs. This mock was based on that behavior. Also worth noting that the hook equivalent will throw a React-themed error regarding dynamic behavior not being available in the server. The results will not match between server and client which is well known in the web community and results in hydration errors. There, you would use media queries and dynamic styles (100%, 3rem, etc).

Since we don't actually hydrate the views from an RSC payload before the JS loads, hydration isn't entirely relevant here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants