jamal
jamal

Reputation: 1105

React Native App LTR to RTL change without restarting the app

Currently I am using I18nManager for changing LTR to RTL, But its working only after restarting the app, My code is given below

 import {I18nManager} from 'react-native';
 import RNRestart from 'react-native-restart';

changeLtrToRtl=()=>{
    I18nManager.forceRTL(true);
    RNRestart.Restart();
}

Is there some other method for implementing LTR to RTL change without restarting the app?

Upvotes: 6

Views: 5563

Answers (1)

kubilay salih
kubilay salih

Reputation: 492

You can use Context API to set direction of application and consume the value from child components. With that value you can conditionally change the direction of components.

// using I18nManager you can get initial direction of device or you can use async storage or both of them as combined. i really dont care now...
const LanguageDirectionContext = createContext({
  direction: 'ltr'
})

const LanguageDirectionProvider = ({ children }) => {
  const [direction, setDirection] = useState('ltr')

  const toggleDirection = () => {
    setDirection(direction === 'ltr' ? 'rtl' : 'ltr')
  }

  useEffect(() => {
    // use I18nManager to force direction and use asyncstorage to save the current direction to device.
  }, [direction])

  return (
    <LanguageDirectionContext.Provider value={{
      direction,
      toggleDirection
    }}>
    {children}
    </LanguageDirectionContext.Provider>
  )
}

Create direction dependent component and wrap it with provider that we created. Also its good practice to use hooks for that context. Check this out.

const useDirection = () => {
  const context = useContext(LanguageDirectionContext)

  if (!context) {
    throw new Error('You forgot the language provider!')
  }

  return context
}

Direction dependent text component example.

const MyCustomTextComponent = ({ children, style, ...rest }) => {
  const { direction } = useDirection()

  // i cant understand that the direction of text correct right now. maybe you dont need textAlign property.
  return <Text style={[style, { writingDirection: direction, textAlign: direction === 'ltr' ? 'left' : 'right' }]} {...rest}>{children}</Text>
}

If you have any other component that need direction, you can recreate these components with useDirection hook.

Now you can use toggleDirection function to change direction of your components.

const MyDirectionChangerButton = () => {
  const { toggleDirection } = useDirection()
  return (
    <Button title="Change direction." onPress={toggleDirection} />
  )
}

Here full example: https://snack.expo.io/@kubilaysali/frowning-waffles

Upvotes: 9

Related Questions