I'm trying to stream video from the camera in a View with React Native. The problem is, if the user presses the home button, temporarily leave the app and switch back, the stream URL will be changed.
So I need to update the URL in a function similar to viewWillAppear as in native iOS framework. Any suggestion on this?
Yes #Danny Want is right you can use AppState. It can be used like this:
getInitialState: function() {
return {
currentAppState: AppState.currentState,
};
},
componentDidMount: function() {
AppState.addEventListener('change', this._handleAppStateChange);
},
componentWillUnmount: function() {
AppState.removeEventListener('change', this._handleAppStateChange);
},
_handleAppStateChange: function(currentAppState) {
this.setState({ currentAppState, });
},
render: function() {
return (
<Text>Current state is: {this.state.currentAppState}</Text>
);
},
Do what you wanna do in the AppState handler: _handleAppStateChange. For more details please check out here
Related
I'm developing a social network, and I have the Home screen, where a feed is loaded and a Post screen.
How to trigger reloading only when a post is created?
Both screens are inside a Bottom Navigator.
if you wanna you components to be reloaded with states then you can use redux or react context.
but if you are not using those then you cannot reload but you can call function when tab is changed or pressed refer this https://reactnavigation.org/docs/bottom-tab-navigator/#events
and call your functions inside this to reload the data.
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Do something manually
// ...
});
return unsubscribe;
}, [navigation]);
or even you can use focus method
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// do something
});
return unsubscribe;
}, [navigation]);
Expo Camera is working in my code.
Current Code
const { status } = await Permissions.askAsync(Permissions.CAMERA);
if (status === 'granted') {
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
mediaTypes: ImagePicker.MediaTypeOptions.Images,
});
}
if status === 'granted', camera opens.
What I want to do
I wanna change text 'Cancel' to Japanese on the bottom.
Is there any way to set locale?
I would appreciate it if you could give me any advice.
The dialog block should be native and language should becomes your phone's setting language, maybe you could try to change your phone to Japanese local and restart the app.
If you want to customer the dialog, you could detect and using Alert.alert to show what you want to show, but request may be native to ask again.
Something like this I used before:
Alert.alert(
I18n.t('Permission_requireTitle'),
I18n.t('Permission_camera'),
[
{
text: I18n.t('Permission_btn1'),
onPress: () => {
console.log("Permission denied");
Actions.pop();
},
style: "cancel"
},
{
text: I18n.t('Permission_btn3'),
onPress: () => {
AndroidOpenSettings.appDetailsSettings();
}
}
],
{ cancelable: false }
);
Or maybe it have language setting in your permission package you could try to find.
I am trying to navigate my app from outside of a component. Specifically, I am using a fetch interceptor and I want to navigate whenever an error response is received.
I followed the example here: https://reactnavigation.org/docs/navigating-without-navigation-prop/
However, my app is still giving me an error saying that either a navigator isn't rendered or the navigator hasn't finished mounting:
Screenshot of app with error message
As far as I can tell, neither of those situations apply. The app is loaded and rendered with a navigator in place before I try to actually navigate
My App.jsx:
// ... imports and so on ...
fetchIntercept.register({
response: (response) => {
if (response.status === 401) {
// Unverified subscription
RootNavigation.reset({ index: 0, routes: [{ name: 'Intercept' }] });
}
return response;
},
});
{ ... }
const InterceptNavigator = createStackNavigator(
{
Application: {
screen: ApplicationScreen,
},
Intercept: {
screen: SubscriptionInterceptScreen,
},
},
{
initialRouteKey: 'Application',
},
);
const App = createAppContainer(InterceptNavigator);
export default () => {
React.useEffect(() => {
RootNavigation.isMountedRef.current = true;
return () => { RootNavigation.isMountedRef.current = false; };
}, []);
return (
<NavigationContainer ref={RootNavigation.navigationRef}>
<App />
</NavigationContainer>
);
};
RootNavigation.js:
import * as React from 'react';
export const isMountedRef = React.createRef();
export const navigationRef = React.createRef();
export function navigate(name, params) {
if (isMountedRef.current && navigationRef.current) {
navigationRef.current.navigate(name, params);
}
}
export function reset(options) {
if (isMountedRef.current && navigationRef.current) {
navigationRef.current.reset(options);
}
}
I also inserted a number of console logs throughout and all of them showed that the app is loaded, that the navigationRef is current, and that the isMountedRef is also current before the app tries to navigate
Try .resetRoot() instead of .reset(). I think .reset() needs a state as an argument.
Found the solution. The issue is that I had a mixture of version 4 and version 5 code (and was referring to mixed documentation).
To fix the issue I removed references to version 5 code and then followed the steps on this page to get the navigator working: https://reactnavigation.org/docs/4.x/navigating-without-navigation-prop/
I'm using NativeBase in a React Native app. I'm trying to show a Toast component based on an error that is set in an redux action because it happens via a call to the API.
It will show now, but currently I get the warning message:
Warning: Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.
I'm not sure how I could bind this or what I could do to solve the warning.
Render Method
render() {
return (
<View>
{this.renderError()}
{this.renderForm()}
</View>
);
}
Render Error Method
renderError() {
if (this.props.error.type === 'server') {
return (
Toast.show({
text: this.props.error.message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
);
}
}
Versions
React Native: 0.55.4
Native Base: 2.4.5
Edit: Adding an example for clarity
I need to show a Toast based on the response from the server. For example, if the username and password don't match an account, I need to render the Toast.
Solution:
I ended up creating a ToastService:
import { Toast } from 'native-base';
function showToast(message) {
return (
Toast.show({
text: message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
);
}
export default {
showToast
};
and now in my action I can just call:
ToastService.showToast(data);
You can create a function and call this one outside. But make sure your app is wrap with the Root component of native-base. No need to return a component like you do. Calling this function gonna show the toastr and now you have the freedom to call from anywhere. But make sure Root component wrap your app.
import { Toast } from 'native-base';
export const toastr = {
showToast: (message, duration = 2500) => {
Toast.show({
text: message,
duration,
position: 'bottom',
textStyle: { textAlign: 'center' },
buttonText: 'Okay',
});
},
};
Now inside your action you can call the toastr function
toastr.showToast('Verication code send to your phone.');
Or in redux actions
const signup = values => dispatch => {
try {
// your logic here
} catch (error) {
toastr.showToast(error.message)
}
}
I solved this issue by using React Hooks.
() => {
useEffect(() => {
if(error) {
Toast.show({
text: this.props.error.message,
buttonText: 'Okay',
duration: 5000,
type: 'danger'
})
}
})
return (
<View>
{this.renderForm()}
</View>
);
}
Check React Native Seed for this implementation
https://reactnativeseed.com/
Like Dwayne says above, you need to use useEffect so that Toast is called before the render cycle. You can wrap this is a component like so:
const ErrorToast: React.FC = () => {
const {state} = useCollections();
useEffect(() => {
if(state.errored) {
Toast.show({
text: 'Oops. There has been an error',
duration: 2000
});
}
});
return null;
}
And then simply include it as <ErrorToast />
I need to offer a list of options in a modal. Android has <Picker> which on click presents the items. iOS has Alert.
On Android I want to use the <Picker> in dialog mode functionality without having to create an element, just like the Alert API on iOS. Is this possible?
Anyway to trigger a "press" on the <Picker> to get its dialog modal?
So, this is a way of doing what you want. You could show/hide the picker by wrapping it in another Component. This is an old example I used once:
const MyPicker = React.createClass({
getInitialState() {
return { displayed: true };
},
show() {
this.setState({ displayed: true });
},
hide() {
this.setState({ displayed: false });
},
render() {
if (this.state.displayed) {
return <Picker {...this.props}>{this.props.children}</Picker>;
} else {
return null;
}
},
});