-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Alternative to className property on View #1318
Comments
There is not going to be a replacement API for adding |
How would we use setNativeProps to combine our additional className with the one(s) generated by react-native-web. Is there a concrete example of this in the react-native-web documentation? |
@RyanThomas73 Use setNativeProps inside component did mount. |
Yes use it like any other instance method. You can read more in the "direct manipulation" docs. |
Oh yes it will. Use a |
@necolas Thanks I'll try using the It's important for us to have a way to use the features that react-native-web either decides not to support or has not yet had time to implement. |
People need to share relevant use cases (not solutions) |
It's deprecated on react-native-web necolas/react-native-web#1318 (comment) necolas/react-native-web#1146 (comment) necolas/react-native-web#1299
I want to add a hover on my react-native-paper menu, I'd like to hook a css and target the div, but I can't without getting warning, any solution (I just give you a specific use case) |
@necolas We're doing server side rendering with RNW, but we also need media queries for our desktop application as it's important that the app looks correct on the first render or the markup coming from the server. We need to inject a className to our components to do this, but currently as we need a ref to the component and run I'm mentioning this as an use case that we have. Similar to the points brought up here: #1146 (comment) |
@necolas but to set a |
https://github.com/necolas/react-native-web/releases/tag/0.13.0 |
Similar to @TheMightyPenguin, I am trying to server-side render RNW using Next.js. If I use I've come up with 2 solutions:
I've relied on I know @necolas recommends against using The unfortunate part, of course, is that Is this considered a strong enough use case for using the If not – is anyone aware of a package that generates CSS modules based on custom selectors, which could also work for server-side rendering/Next.js and RNW? I'm happy to share minimal code to illustrate if that would help. |
@nandorojo I actually tried to make it work with We ended up doing an approach similar to this one, and when rendering on the server, we use the |
@TheMightyPenguin I see, thanks for the heads up. Maybe I could rely on the same solution. The downside is that for some percentage of users, the user agent will be wrong, so it doesn't feel like a safe workaround. If I rely on screen size on from the server, someone could resize their screen between the time that they first opened the URL and the time the client renders. If they resize to a different breakpoint during that time, the client & server props won't match, and the correct styles won't apply since the Next.js app will break. I would definitely prefer to keep this all in JS if I could. It makes the most sense, and I agree that it's the right direction for RNW. Unfortunately, the trade off of losing good SEO seems too high. And a solution that doesn't work for every user makes me a bit nervous to put in production. |
@nandorojo is that actually an use case where your users are resizing the page much? In our case it's not that common, I think it's an edge case you shouldn't worry too much about 😉 . If users resize on the client and the page has already rendered, it's fine as styles will be handled in JavaScript, so styles will change nicely. Also on the server you cannot rely on a screen size as you don't have that information, but instead on the user agent string which will look something like this:
https://deviceatlas.com/blog/list-of-user-agent-strings So you use that to determine what kind of device the user is using (mobile, tablet, desktop, ...), and then apply styles based on that, and there are also many libraries that parse this string and help you to detect the device. Regarding SEO, why is that a concern? Rendering the mobile/tablet/desktop version of your markup shouldn't affect SEO if all follow semantic HTML practices, or if you have things like JSON-LD structured data, so I'm not sure you would lose your SEO score. |
@TheMightyPenguin Yeah, I don't think it's a super common situation. It's just an edge case I would like to prevent. I'll keep testing it though. I think you can get the screen width using The reason I would sacrifice SEO would be if I lazy-load the components and stick with JS styles. React SSR requires that all components from the first client render & the server render have the same |
@nandorojo Nice! I didn't know about |
That's what I thought:
Turns out, React requires your server and client to be the same, and if they aren't it will still render whatever the server generated.
There's more info about that on Google's website: https://developers.google.com/web/updates/2019/02/rendering-on-the-web In any case, there appears to be a trade-off with deprecating If you have to do a full re-render, you're getting "one app for the price of two" performance-wise, as Google puts it. I guess we can bank on phones and internet getting faster, so maybe this won't be a problem going forward. The downside is that I don't know how to check from the client if the props are different from the server. So if I want to avoid the edge case of client and server not matching for the edge case I described above, it might require a re-render no matter what. I appreciate your help with this, by the way. |
Yeah, I guess the "double render" is a price we're going to pay in some requests, but I doubt it will be that often, we'll be monitoring our logs to see often we get a props mismatch due to this to see if it's a problem worth solving 👍 For a bit more context, what we do is something like:
At the begining I was skeptic about using a device name instead of a breakpoint, but it's actually quite nice! And likewise 👍 It's nice talking with others with the same challenges 😄 ! |
I see, thanks for sharing. One thing I did notice just now - while that might work for server side rendering, it doesn't work for Next.js's Static Site Generation. I should have been more clear in my wording earlier for what I'm using. Static Site Generation can't rely on the user agent since the pages are generated at build time. And so, a forced re-render would be necessary basically every time. Also, doesn't user agent only tell you the device but not size? What if a desktop browser isn't full screen width? |
Here is my current solution. The downside is that there is a flash of unstyled components 🤕 const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
function useScreenWidth() {
const [width, setWidth] = useState(
Platform.select({ web: 0, default: Dimensions.get('window').width })
)
useIsomorphicLayoutEffect(() => {
if (Platform.OS === 'web') {
const { width } = Dimensions.get('window')
if (width >= breakpoints[0]) {
setWidth(width)
}
}
}, [])
useEffect(() => {
const listener = (event) => {
setWidth(event.window.width)
}
Dimensions.addEventListener('change', listener)
return () => {
Dimensions.removeEventListener('change', listener)
}
}, [])
return width
} I don't know the performance implications of In an effort to not spam people who are subscribed to this issue, I'll be moving discussion to nandorojo/dripsy#1. Please follow up there if you are having issues or have solved this problem in another way. |
@nandorojo right, with static site generation the only way would be with CSS media queries 😢
Yeah, you're right, it's not a perfect solution but is a place to start! |
An update in case anyone is wondering: I removed SSR support for Dripsy and my app lol. Trying to maintain media queries with CSS hacks just wasn't worth separating from RNW. |
@nandorojo totally agree. In our case we rely on the user agent on the server side, it has worked well so far, but yeah we tried going down that route and it was painful. |
@nandorojo I stopped using Fresnel with Next JS + Native Web after too much struggle. But then I found another one working like a charm, more like a media queries within styles |
@necolas I use React Native Paper, a Material UI alternative for React Native. In Material UI, for each component and each HTML tag that's part of a component like TextView, Button, Avatar, div, p, input, span etc. they injected special classes like While React Native Paper works normally for most components, some pose some very light problem that can be solved with 1 CSS Rule. But we must be able to target a Component with class to rule it in external CSS. We know we should stay away, but hacking components with CSS in Next JS or Web side doesn't have to be mixed up with React Native if it already display well. Also, instead of asking React Native Paper staff of other packages staff to fix all Single CSS rule problem, we could work around on them all with classes. Maybe the |
Is your feature request related to a problem? Please describe.
We use the
className
property in a few select cases to apply css rules that we otherwise cannot apply through styles. (e.g. ::-webkit-scrollbar rules, etc). After updating to the latest version of react-native-web we now receive continuous warnings stating that theclassName
property is deprecated without providing any documentation for an alternative to achieve the same result.Describe a solution you'd like
Provide alternative instructions on how we can achieve the same result without using the
className
property.Describe alternatives you've considered
We currently patch the
react-native-web
package after installing to comment out the warning line. While this suppresses the repeated errors it does not provide us a solution for upgrading in the future.Additional context
react-native:
0.59.2
react-native-web:
0.11.0
The text was updated successfully, but these errors were encountered: