vitalets/react-native-extended-stylesheet

Using static theme (change theme without app reload)

sm2017 opened this issue · 8 comments

1- Is it possible to use static theme and no app reload to theme change? for example when I want to change theme , Just call EStyleSheet.build and forceUpdate again

2- Is dynamic theme need cashing ? IS dynamic theme need stylesheet creation in every render() call?

  1. So you are talking about dynamic theme change, not static. Calling forceUpdate is not enough, because it will update only root component, but not children (see: facebook/react#3038).
    UPDATE: forceDeepUpdate() is under discussion facebook/react#7759

  2. Yes, the best way is to pre-built both themes and keep them cached. Please have a look on dynamic theme example and this discussion.

In my first question I don't talk about dynamic theme I talk about static theme .

This library is awesome but I have 2 major problem
First is orientation change is not supported (#9) and Really I need orientation change

Second problem is static theme is very easy to use but dynamic is not as easy as static and also If I have 20+ theme . I MUST prebuild all themes and it need 20x resources
Also it is not possible to have live theme change that means user who run App cannot define or modify theme . because prebuild is needed

@vitalets any idea?

Your case is interesting. I agree that caching 20+ themes looks overhead and the best approach is to dynamically build selected theme.

Currently this is not supported in EStyleSheet. But it can be done by changing two places as I described here: #22 (comment)

I would appreciate I you play with it and share the results.
But another important question for me - will it be possible to re-render all components after dynamic theme change. I think it should be checked first.
Hope this helps.

@vitalets I think we can re-render all components by do following

Assume we have <App/> and it contain whole application , we can surround it with <Theme>

<Theme name="dark" status="loaded">
    <App/>
</Theme>

When we change theme , we change status to loading and when theme is loaded , status is loaded

function Theme (props) {
    if(props.status=="loaded")
      return <View>{props.children}</View>;
    else
      return <Text>Please wait ...</Text>;
}

(i know we lost states , but it is better than reloading application)

Any update?

@sm2017 sorry for delay, lost this thread. Approach looks good to me!
So the goal is to re-calculate all styles after theme change - I will try to find time for that.

By the way, could you show the whole example how you see this? For example with <Switch> component that toggles theme.

My method is in a HOC, but you can adapt it…
My solution for recompiling styles when resizing the window is as follows
at the onLayout event hide and redisplay the component to take into account the new compiled style

withResponsive.ts

import React, { View, ComponentType, FunctionComponent, useState } from 'react'
import EStyleSheet from 'react-native-extended-stylesheet'

const styles = EStyleSheet.create({
  container: {
    flex: 1,
  },
})

export const withResponsive = (Component: ComponentType): ComponentType => {
  const Responsive: FunctionComponent<unknown> = () => {
    const [show, setShow] = useState<boolean>(true)

    const build = () => {
      setShow(false)
      EStyleSheet.build()
      setShow(true)
    }

    return (
      <View style={styles.container} onLayout={build}>
        {show ? <Component /> : null}
      </View>
    )
  }

  return Responsive
}