Probably!
Environment:
OS: Linux 4.4
Node: 7.10.1
Yarn: 1.0.1
npm: 4.2.0
Watchman: 4.7.0
Xcode: N/A
Android Studio: Not Found
Packages: (wanted => installed)
react: 16.2.0 => 16.2.0
react-native: 0.52.2 => 0.52.2
Target Platform: Android
I have an app that created by awesome React-native and my layout designed to be in RTL mode. I've set up an option for forcing the layout to be RTL.
But my option doesn't works in first app load after installing. This feature applies in second run
I wrote this option in our index.js:
import React, { Component } from 'react';
import { I18nManager } from 'react-native';
import { Provider } from 'react-redux';
I18nManager.forceRTL(true);
class App extends Component {
render() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<MainStack />
</PersistGate>
</Provider>
);
}
}
export default App;
After a week finally i found a logicly way to solve this issue with using Redux & react-native-restart plugin. I'm also use a nice splash screen to user don't show a restarting progress for this purpose.
So let's dive into code:
Redux action:
export const GET_APP_LAYOUT_DIRECTION = 'GET_APP_LAYOUT_DIRECTION';
export const SET_APP_LAYOUT_DIRECTION = 'SET_APP_LAYOUT_DIRECTION';
export const getAppLayoutDirection = () => ({
type: GET_APP_LAYOUT_DIRECTION,
});
export const setAppLayoutDirection = direction => ({
type: SET_APP_LAYOUT_DIRECTION,
direction
});
Redux Reducer:
import {
GET_APP_LAYOUT_DIRECTION,
SET_APP_LAYOUT_DIRECTION,
} from '../actions/app';
const initialState = {
layout: 'ltr',
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case GET_APP_LAYOUT_DIRECTION:
return {
...state,
};
case SET_APP_LAYOUT_DIRECTION:
return {
...state,
layout: action.direction,
};
default:
return state;
}
};
export default reducer;
Home Screen:
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import RNRestart from 'react-native-restart'; // Import package from node modules
import { getAppLayoutDirection, setAppLayoutDirection } from '../actions/app';
class Home extends PureComponent {
constructor(props) {
super(props);
this.props.dispatch(getAppLayoutDirection());
if(this.props.layout === 'ltr'){
this.props.dispatch(setAppLayoutDirection('rtl'));
RNRestart.Restart();
}
}
componentDidMount() {
if(this.props.layout && this.props.layout === 'rtl'){
SplashScreen.hide();
}
}
}
const mapStateToProps = (state) => {
const { layout } = state.app;
return {
layout
};
}
export default connect(mapStateToProps)(Home);
works great!!! BTW
layout can also be check by.
if (!I18nManager.isRTL) {
RNRestart.Restart();
}
In my case, react-native-restart is not an option because it yields a memory leak within RN itself (on Android after restarting, seemingly related to OKHTTP). The app can land in a terrible constant-restart-then-crash state (which can detriment an app's rating on Google Play). So beware of relying on programmatically restarting an app!
I have a same issue. Is there any solution to force app to RTL ?
ping.. (has the same issue)
PS: As rn-core devs tend to close critical issues posted by users strategically after a particular period of inactivity in a ticket.
Warning about using react-native-restart for this (and in general): if any problem occurs during your restart process, the app can fall into crash-restart loop that may see your app get rated as poor quality on app stores. It often works, but it isn't a good solution to this LTR<>RTL problem.
Another workaround would be adding:
I18nUtil.getInstance().allowRTL(this, false);
to
public void onCreate() {
in your MainApplication.java file
Also, don't forget to add
import com.facebook.react.modules.i18nmanager.I18nUtil;
at the top of your MainApplication.java
Another workaround would be adding:
I18nUtil.getInstance().allowRTL(this, false);
to
public void onCreate() {
in your MainApplication.java file
@matanelgabsi , @HossamSamir What about iOS?
@sm2017 Add the following
#import <React/RCTI18nUtil.h>
and
[[RCTI18nUtil sharedInstance] allowRTL:YES];
[[RCTI18nUtil sharedInstance] forceRTL:YES];
inside didFinishLaunchingWithOptions
Most helpful comment
Another workaround would be adding:
I18nUtil.getInstance().allowRTL(this, false);to
public void onCreate() {in your MainApplication.java file