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

[Expo][React Navigation]Device-Context doesn't work #247

Closed
atanaskanchev opened this issue Aug 28, 2023 · 9 comments · Fixed by #271
Closed

[Expo][React Navigation]Device-Context doesn't work #247

atanaskanchev opened this issue Aug 28, 2023 · 9 comments · Fixed by #271

Comments

@atanaskanchev
Copy link

Following the guide for Enabling Device-Context Prefixes, importing useDeviceContext(tw) in the entry point of the app has no effect, i.e dark mode, breakpoints are not being intercepted. Adding it to each screen however works. Any advice?

@jaredh159
Copy link
Owner

can you double check your setup and config? lots of folks have this working for them, so i think there might be something amiss about how you've got it configured. for instance, i'm struggling to remember this off the top of my head, but i think if you use useDeviceContext then you need to be sure you're importing your own version of tw from a local file everywhere you're using it, instead of pulling it straight from twrnc, similar to how you'd need to do so if you were using a custom tailwind config file.

if you still can't get it working, could you make a minimal repro i could look at? or is your project open source to where i could examine the code?

@atanaskanchev
Copy link
Author

atanaskanchev commented Aug 30, 2023

Hi @jaredh159 , I've created a minimal reproducible example with expo and react navigation. The dark mode background is not being changed on changing the device theme

import { StatusBar } from "expo-status-bar";
import tw, { useDeviceContext } from "twrnc";
import RootStackNavigator from "./navigation/root-stack-navigator";

export default function App() {
  useDeviceContext(tw);

  return (
    <>
      <RootStackNavigator />
      <StatusBar style="auto" />
    </>
  );
}
import { Text, View, useColorScheme } from "react-native";
import tw from "twrnc";

const Home = () => {
  const scheme = useColorScheme();
  return (
    <View
      style={tw`bg-red-500 flex-1 dark:bg-blue-500 justify-center items-center`}
    >
      <Text style={tw`text-3xl`}>{`Current colour scheme: ${scheme}`}</Text>
    </View>
  );
};

export default Home;

Simulator Screenshot - iPhone 14 Pro Max - 2023-08-30 at 11 36 23

@atanaskanchev atanaskanchev changed the title [Expo] Device-Context doesn't work [Expo][React Navigation]Device-Context doesn't work Aug 30, 2023
@atanaskanchev
Copy link
Author

An observation: adding useColorScheme() and useDeviceContext(tw) in a screen fixes the issue, but only in that particular screen. To get it working in the Other screen, I must use useColorScheme()

Home screen: works ok

import { useNavigation } from "@react-navigation/native";
import { Text, TouchableOpacity, View, useColorScheme } from "react-native";
import tw, { useDeviceContext } from "twrnc";

const Home = () => {
  const scheme = useColorScheme();
  useDeviceContext(tw);

  const { navigate } = useNavigation();

  return (
    <View
      style={tw`bg-red-500 flex-1 dark:bg-blue-500 justify-center items-center`}
    >
      <Text style={tw`text-3xl`}>Home</Text>
      <Text style={tw`text-3xl`}>{`Current colour scheme: ${scheme}`}</Text>
      <TouchableOpacity
        style={tw`bg-yellow-500 p-3`}
        onPress={() => navigate("Other")}
      >
        <Text>"Go to other screen"</Text>
      </TouchableOpacity>
    </View>
  );
};

export default Home;

Other screen: doesn't work

import { useNavigation } from "@react-navigation/native";
import { Text, TouchableOpacity, View } from "react-native";
import tw from "twrnc";

const Other = () => {
  // const scheme = useColorScheme();
  const { navigate } = useNavigation();

  return (
    <View
      style={tw`bg-red-500 flex-1 dark:bg-blue-500 justify-center items-center`}
    >
      <Text style={tw`text-3xl`}>Other</Text>
      {/* <Text style={tw`text-3xl`}>{`Current colour scheme: ${scheme}`}</Text> */}
      <TouchableOpacity
        style={tw`bg-yellow-500 p-3`}
        onPress={() => navigate("Home")}
      >
        <Text>"Go to home screen"</Text>
      </TouchableOpacity>
    </View>
  );
};

export default Other;

@atanaskanchev
Copy link
Author

atanaskanchev commented Aug 30, 2023

Ok, I've got the colour scheme changes working here, but not sure if this is the correct approach:

Move the useDeviceContext hook to the RootStackNavigator and pass the colour scheme as a key argument to the NavigationContainer

import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import React from "react";
import { useColorScheme } from "react-native";
import tw, { useDeviceContext } from "twrnc";
import Home from "../screens/home";
import Other from "../screens/other";

export const RootStack = createNativeStackNavigator();

const RootStackNavigator = () => {
  const scheme = useColorScheme();
  useDeviceContext(tw);

  return (
    <NavigationContainer key={scheme}>
      <RootStack.Navigator>
        <RootStack.Screen name="Home" component={Home} />
        <RootStack.Screen name="Other" component={Other} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
};

export default RootStackNavigator;

I suppose to have support for breakpoints we should pass the useWindowDimensions() as a key as well

@atanaskanchev
Copy link
Author

I've just realised that this seems to be the same issue as #112

@jaredh159
Copy link
Owner

yeah, i was thinking the same thing about #112. i also had one other thought this morning -- would you be able to test one thing real quick? run npm i [email protected] and see if the problem persists. 3.6.4 introduced a perf optimization that prevents re-renders, and i'm wondering if it's aggravating this issue. worth ruling out before we dig deeper.

@atanaskanchev
Copy link
Author

Using 3.6.3

The behavour is the same.

Simulator.Screen.Recording.-.iPhone.14.Pro.Max.-.2023-08-30.at.15.57.15.mp4

Adding back the const scheme = useColorScheme(); to the screen kind of works, but the modes are mixed up

import { Text, View, useColorScheme } from "react-native";
import tw from "twrnc";

const Home = () => {
  const scheme = useColorScheme();
  return (
    <View
      style={tw`bg-red-500 flex-1 dark:bg-blue-500 justify-center items-center`}
    >
      <Text style={tw`text-3xl`}>{`Current colour scheme: ${scheme}`}</Text>
    </View>
  );
};

export default Home;
Simulator.Screen.Recording.-.iPhone.14.Pro.Max.-.2023-08-30.at.15.59.40.mp4

@Marinolinderhof
Copy link

I created a custom hook, Which is far from ideal but it consider this as a work around

//useTWTheme.tsx
import { useColorScheme } from "react-native";
import tw, { useDeviceContext } from "twrnc";

function useTWTheme() {
  const colorScheme = useColorScheme();
  useDeviceContext(tw);

  const isDark = colorScheme === "dark";

  return { isDark, c: tw.style };
}

export default useTWTheme;

This solves a couple of things for me:
tw'pt-2 bg-blue-100' gives me errors and therefore i want to force myself to use the tw.style prop.

  const colorScheme = useColorScheme();
  useDeviceContext(tw);

will make sure the darkmore classes work. Downside is that you need to import this in all components (or at least all top route components seems the. _layout.js will not propagate properly.

const myComp = () => {
  useTWTheme();
  // or 
 const {c, isdark} = useTWTheme();
}

This only makes it easier for me not better.

@jaredh159
Copy link
Owner

v4.0.0 (beta available now with npm install twrnc@next) exposes a memoization buster (tw.memoBuster) that can be passed as a key to break memoization.

see #271. when that is merged, i'm going to close this. if memoization issues are still found, let's consolidate discussion at #112.

@jaredh159 jaredh159 mentioned this issue Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants