React Native : How to get device Screen Brightness and render it - react-native

I`m creating an React App to display device Info. I want to render Screen Brightness level, not in Console. How do I do it?
DeviceBrightness.getSystemBrightnessLevel().then(function(luminous) {
console.log(luminous)
})
I expected to render the screen brightness level, not to display in console

import DeviceBrightness from 'react-native-device-brightness';
export default class App extends Component{
constructor(props){
super(props);
this.state = {
isLoaded: false,
brightness: 0,
};
}
componentWillMount() {
DeviceBrightness.getSystemBrightnessLevel()
.then((luminous) =>{
this.setState({
brightness: luminous,
isLoaded: true,
});
});
}
render() {
return (
<View style={styles.container}>
<Text style={styles.instructions}>{this.state.brightness}</Text>
</View>
);
}
}

import DeviceBrightness from 'react-native-device-brightness';
export default class YourComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
brightness: 0
};
}
componentDidMount() {
DeviceBrightness.getSystemBrightnessLevel()
.then(luminous => {
this.setState({
brightness: luminous,
isLoaded: true,
});
});
}
render() {
const { isLoaded, brightness } = this.state;
if (!isLoaded) {
return {/*loading view*/}
} else {
return (
<Text>{brightness}</Text>
);
}
}
}

Related

'Warning: Can\'t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application

im building a react native application ,still i have 2 screens
1.Enter mobile
2.Verify Otp
EnterUserInfo.js
class UserInfoInput extends Component {
constructor(props) {
super(props);
this.state = { formValid:true,
validMobileNumber:false,
.
.}}
componentWillReceiveProps(nextProps) {
if(nextProps.common.isFetching===false) {
this.props.navigation.navigate('VerifyOtpScreen')
.
.
} else {
this.setState({isLoading:true})
}}
onPressNext=()=> {
this.props.sendOtp(payload)}
render() {
return (<View/>)
}
}
}
function mapStateToProps(state) {
return {
common: state.common
}
}
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ sendOtp }, dispatch)
}
}
export default connect(mapStateToProps,mapDispatchToProps)(UserInfoInput);
Here user enter the phone number ,and trigger an action sendOtp,response will be in the reducer and it will be available in the componentwillrecieveprops() lifecycle.
VerifyOtp.js
class VerifyOtp extends Component {
constructor(props) {
super(props);
this.state = { oneTimePIN: '' ,
.};
}
componentDidMount(){
this.setState({ phoneNumber:this.props.common.phone});
}
componentWillMount() {
setTimeout(() => {
this.setState({ isResendDisabled: false, opacity: 1 });
}, 30000);
}
componentWillReceiveProps(nextProps){
//do operation
}
onPressNext=()=>{
if(this.state.oneTimePIN=='') {
this.setState({showNotification:true})
}
else {
this.onSubmit()
}
}
onSubmit=()=>{
this.props.verifyOtp(payload)
}
onResendOtp=()=>{
this.props.sendOtp(payload,locationData)
this.setState({ isResendDisabled: true, opacity: 0.5 });
setTimeout(() => {
this.setState({ isResendDisabled: false, opacity: 1 });
}, 30000);
}
render() {
return (<View><Elements></View>)
}
}
function mapStateToProps(state) {
return {
common: state.common
}
}
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ verifyOtp,sendOtp }, dispatch)
}
}
export default connect(mapStateToProps,mapDispatchToProps)(VerifyOtp);
VerifyOtp screen used to verify the otp.
The problem is,If i move back to enterUserinfo screen and move again to the verifyOtp screen im getting the warning message
'Warning: Can\'t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application
What is the reason for the warning , and how tackle the issue?
This happens when you call an async function followed by setstate.
A simple work around would be like this:
constructor(props) {
this.state = {
...
this.isCancelled: false
}
}
componentWillMount() {
setTimeout(() => {
!this.state.isCancelled && this.setState({ isResendDisabled: false,
opacity: 1 });
}, 30000);
}
and in componentWillUnmount
componentWillUnmount() {
// setting it true to avoid setState waring since componentWillMount is async
this.state.isCancelled = true;
}

Setting state with a function in another file

Without attempting to update my state, the initial location in state is presented correctly. When I set state using a helper function, nothing is displayed in my app. What am I doing wrong? Additionally, logging props inside ShowLocation's render() shows that the coords{lat:xx,long:xx} are coming through correctly.
App.js
import * as helpers from './src/helpers';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = globals.initial_state;
}
componentDidMount(){
this.setState({location:helpers.getLocation()});
}
render() {
return (
<View>
<ShowLocation coords={this.state.location} />
</View>
);
}
}
ShowLocation.js
class ShowLocation extends Component {
constructor(props){
super(props);
}
render(){
return(
<View>
<Text>{this.props.coords.lat}, {this.props.coords.long}</Text>
</View>
)
}
};
helpers.getLocation:
export function getLocation(){
coords = {};
navigator.geolocation.getCurrentPosition(
(position) => {
coords['lat'] = position.coords.latitude
coords['long'] = position.coords.longitude
},
(error) => this.setState({ navigatorError: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
return coords;
}
Did you tried:
componentDidMount(){
this.setState({ location: getLocation().bind(this) });
}
Or, same thing, but cleaner code:
constructor() {
// other stuff
this.getLocation = getLocation().bind(this)
}
componentDidMount(){
this.setState({ location: this.getLocation() });
}
Edit:
You must import { getLocation} from 'path/of/file'

React Native show Homepage if is connected

How to show React Native Homepage if is connected?
and if is not connected, Show a full screen photo? (with a Condition by NetInfo)
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
NetInfo
} from 'react-native';
function ConnectionOk() {
return (
<View >
<Text >
Welcome to React Native1!
</Text>
<Text >
To get started, edit App.js
</Text>
</View>
);
}
function ConnectionNotOk() {
return (
<View>
<Text>not Connected ...</Text>
</View>
);
}
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props)
this.state = {
isConnected: false,
isMounted: true
};
}
componentDidMount() {
// my way of checking internet, don't use both methods
// this.checkInternetConnection();
// Its good idea to attach event listener here, or in constructor
NetInfo.isConnected.addEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
};
componentWillUnmount() {
this.setState({
isMounted: false
});
// Its good idea to remove all event listener here
NetInfo.removeEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
};
checkInternetConnection() {
fetch("https://httpbin.org/ip")
.then(response => response.json())
.then(responseJson => {
//update the state only when component is mounted, else it will throw warning
if (this.state.isMounted) {
this.setState({
isConnected: true
});
}
}).catch(err => {
// No internet, redirect to some action if required
})
};
handleFirstConnectivityChange(isConnected) {
if (isConnected) {
this.setState({
isConnected: true
});
} else {
//redirect to some route if required
return <ConnectionNotOk />;
}
render() {
return this.state.isConnected ? < ConnectionOk /> : < ConnectionNotOk />
}
};
}
You can use some flag variable in component state.
From my experience I can say that NetInfo doesn't always gives correct info. ex Internet data is on but no internet connection, NetInfo will return true.
I handle this case by fetching some http api (say https://httpbin.org/ip) which is light and gives correct info about internet.
Also its a good idea to define,add/remove listeners in their appropriate places instead of render.
Try following:
type Props = {};
export default class App extends Component < Props > {
constructor(props) {
super(props)
this.state = {
isConnected: false,
isMounted: true
};
this.checkInternetConnection = this.checkInternetConnection.bind(this);
this.handleFirstConnectivityChange = this.handleFirstConnectivityChange.bind(this);
}
componentDidMount() {
// my way of checking internet, don't use both methods
// this.checkInternetConnection();
// Its good idea to attach event listener here, or in constructor
NetInfo.isConnected.addEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
}
componentWillUnmount() {
this.setState({
isMounted: false
});
// Its good idea to remove all event listener here
NetInfo.removeEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
}
checkInternetConnection() {
fetch("https://httpbin.org/ip")
.then(response => response.json())
.then(responseJson => {
//update the state only when component is mounted, else it will throw warning
if (this.state.isMounted) {
this.setState({
isConnected: true
});
}
}).catch(err => {
// No internet, redirect to some action if required
})
}
handleFirstConnectivityChange(isConnected) {
if (isConnected) {
this.setState({
isConnected: true
});
} else {
//redirect to some route if required
//return <ConnectedNotOk / > ;
}
}
render() {
return (
this.state.isConnected ? <ConnectionOk /> : <ConnectionNotOk />
);
}
}
My full example code.
NetInfo.isConnected.fetch().then(isConnected => {
console.log('First, is ' + (isConnected ? 'online' : 'offline'));
});
function handleFirstConnectivityChange(isConnected) {
console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
if (isConnected == false) {
// your image
}
else{
Actions.HomePage() //if connected go to homepage
}
NetInfo.isConnected.removeEventListener(
'connectionChange',
handleFirstConnectivityChange
);
}
NetInfo.isConnected.addEventListener(
'connectionChange',
handleFirstConnectivityChange
);
i am using react-native-router-flux for redirection
You can achieve it by having isConnected flag in state and using network code set it to true or false dynamically. Then inside the render function use below code
{ this.state.isConnected &&
// Your UI code here
}
I have made some changes in your code. Hope it will help you. Please find complete code below:
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
NetInfo
} from 'react-native';
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isConnected: false,
isMounted: true
};
}
componentWillMount() {
NetInfo.addEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
}
componentWillUnmount() {
this.setState({
isMounted: false
});
// Its good idea to remove all event listener here
NetInfo.removeEventListener(
'connectionChange',
this.handleFirstConnectivityChange
);
}
handleFirstConnectivityChange(connectionInfo) {
if(connectionInfo.type && connectionInfo.type != "none"){
this.setState({
isConnected: true
});
}else {
this.setState({
isConnected: false
});
}
}
render () {
return (
<View>
{this.state.isConnected &&
<View >
<Text >
Welcome to React Native1!
</Text>
<Text >
To get started, edit App.js
</Text>
</View>
}
{!this.state.isConnected &&
<View>
<Text>not Connected ...</Text>
</View>
}
</View>
)
}
}

I want to use scrollTo

I work on a project in React Native and I would like to set my ScrollView position. So I search and I found we should do this with scrollTo but I have an error:
TypeError: Cannot read property 'scrollTo' of undefined
My code:
export default class Index_calendar extends Component {
componentDidMount() {
const _scrollView = this.scrollView;
_scrollView.scrollTo({x: 100});
}
render() {
return (
<ScrollView ref={scrollView => this.scrollView = scrollView}>
{this.renderCalandar()}
</ScrollView>
);
}
}
You can use the InteractionManager to solve this issue.
For instance
InteractionManager.runAfterInteractions(() => this.scroll.current.scrollTo({ x }));
Why not just scrollTo in the render method?
export default class Index_calendar extends Component {
constructor(props) {
super(props);
this.scrollView = null;
}
render() {
return (
<ScrollView ref={scrollView => {
//Sometimes ref can be null so we check it.
if(scrollView !== null && this.scrollView !== scrollView){
this.scrollView = scrollView
scrollView.scrollTo({x: 100});
}}>
{this.renderCalandar()}
</ScrollView>
);
}
}
I found the solution ! we need to use setTimeout like that :
setTimeout(() => {
this.scrollView.scrollTo({x: 100});
}, 1);
You seem to make correct reference. But I suggest to init the reference and make it less error prone:
export default class Index_calendar extends Component {
constructor(props) {
super(props);
this.scrollView = null;
}
componentDidMount() {
const _scrollView = this.scrollView;
if (_scrollView) {
_scrollView.scrollTo({x: 100});
}
}
InteractionManager.runAfterInteractions(() => {
this.scrollRef.scrollTo({
x: 0,
y: 0,
animated: true,
});
});
This worked for me to reset the scroll to top

Update state when user press back button in React Native

I use react-navigation for manage routes. This is my Home component:
class HomeScreen extends React.Component {
constructor(props) {
this.state = {
userProfile: {
firstname: 'John',
avatar: 'john-profile.png',
location: 'Canada',
}
}
}
componentDidMount() {
AsyncStorage.getItem('userProfile', (errs, result) => {
this.setState({userProfile: JSON.parse(result)});
});
}
render() {
return (
<View>
<Image src="{this.state.userProfile.avatar}" />
<Text>Firstname: {this.state.userProfile.firstname}</Text>
<Text>Location: {this.state.userProfile.location}</Text>
</View>
);
}
}
And this is the Profile screen:
class ProfileScreen extends React.Component {
constructor(props) {
this.state = {
userProfile: null,
}
}
componentDidMount() {
AsyncStorage.getItem('userProfile', (errs, result) => {
this.setState({userProfile: JSON.parse(result)});
});
}
save() {
var userSavedProfile = this.state.userProfile;
userSavedProfile.firstname = "Peter";
userSavedProfile.avatar = "peter-avatar.png";
userSavedProfile.location = "EEUU";
this.setState({userProfile: userSavedProfile});
AsyncStorage.setItem('userProfile', JSON.stringify(this.state.userProfile), () => {});
}
render() {
return (
<View>
<Button title="Save" onPress={() => this.save()} />
</View>
);
}
}
When I save the new user information and I press back button in header (react-navigation) the user profile is old, firstname = John, etc... How update state from Home when user press back button and refresh data?
You can use BackHandler from react-native
https://facebook.github.io/react-native/docs/backhandler.html
You can change state inside function of backhandler
I think that your application would need a state manager, where you could store your user information and access it anywhere in the app. You should take a look at Redux. It would fit your needs and the info in your Home screen would automatically update.
but for anyone who will need this functionality in there react native application here is the solution you can try.
using react navigation.
import {withNavigationFocus} from "react-navigation";
class Profile extends Component {
...
}
export default withNavigationFocus(Profile);
There can be two workarounds check it out -
1 Send callback in params
class HomeScreen extends React.Component {
constructor(props) {
this.state = {
userProfile: {
firstname: 'John',
avatar: 'john-profile.png',
location: 'Canada',
}
}
this.getUserData = this.getUserData.bind(this);
}
componentDidMount() {
this.getUserData;
}
getUserData = () =>{
AsyncStorage.getItem('userProfile', (errs, result) => {
this.setState({userProfile: JSON.parse(result)});
});
}
render() {
return (
<View>
<Image src="{this.state.userProfile.avatar}" />
<Text onPress={()=>this.props.navigation.navigate('ProfileScreen', this.getUserData)}>Firstname: {this.state.userProfile.firstname}</Text>
<Text>Location: {this.state.userProfile.location}</Text>
</View>
);
}
}
class ProfileScreen extends React.Component {
constructor(props) {
this.state = {
userProfile: null,
}
}
componentDidMount() {
AsyncStorage.getItem('userProfile', (errs, result) => {
this.setState({userProfile: JSON.parse(result)});
});
}
save() {
var userSavedProfile = this.state.userProfile;
userSavedProfile.firstname = "Peter";
userSavedProfile.avatar = "peter-avatar.png";
userSavedProfile.location = "EEUU";
this.setState({userProfile: userSavedProfile});
AsyncStorage.setItem('userProfile', JSON.stringify(this.state.userProfile), () => {});
//this is the magic
this.props.navigation.state.params.getUserData();
}
render() {
return (
<View>
<Button title="Save" onPress={() => this.save()} />
</View>
);
}
}
2 On HomeScreen Constructor add this (Dirty one)
this.props.navigation.addListener(
'didFocus',
payload => {
this.setState({is_updated:true});
}
);
You can use componentDidUpdate(){...} insted componentDidMount(){}