Reset to default slider value react-native - javascript

I try to create a reset button for the slider that will reset it to the initial value when pressed. My code doesn't show any error but the reset button doesn't work.
This is the Slider component:
import React, {Component} from 'react';
import {Slider,
Text,
StyleSheet,
View} from 'react-native';
import {ButtonReset} from './ResetButton.js'
export class SliderRoll extends Component {
state = {
value: 1,
};
resetSliderValue = () => this.setState({value : 1})
render() {
return (
<View style={styles.container}>
<Slider style={styles.slider}
minimumTrackTintColor={'blue'}
maximumTrackTintColor={'red'}
maximumValue = {2}
value= {this.state.value}
step={0.5}
onValueChange={(value) => this.setState({value: value})}
/>
<ButtonReset resetSliderValue = {this.state.resetSliderValue}/>
<Text style={styles.text} >
{this.state.value}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection:'column',
width: 150,
backgroundColor: 'pink',
marginLeft: 50,
justifyContent: 'center'
},
slider: {
width: 150,
},
text: {
fontSize: 20,
textAlign: 'center',
fontWeight: '500',
},
})
This is the Reset button:
import React, {Component} from 'react';
import {
Text,
View,
StyleSheet,
Image,
TouchableOpacity
} from 'react-native';
export class ButtonReset extends Component{
render(){
return(
<TouchableOpacity style = {styles.container}
onPress= {this.props.resetSliderValue}>
<Image
style={styles.button}
source={require('./restart.png')}
/>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
container: {
width: 50,
alignItems: 'center',
backgroundColor: 'pink',
marginLeft: 50,
marginTop: 10,
},
button: {
width:50,
height:50,
transform: [
{scale: 1}
]
}
})

Here is the problematic piece that stuck out right away:
<ButtonReset resetSliderValue = {this.state.resetSliderValue}/>
I believe it should be:
<ButtonReset resetSliderValue = {this.resetSliderValue}/>
Also, I believe you need to bind this so you can access this for setting state in the resetSliderValue function. I personally like to bind this once in the constructor for any functions that require it so no unnecessary rebinding during rendering:
constructor(props) {
super(props);
this.resetSliderValue = this.resetSliderValue.bind(this);
}

Related

How to Create Top Navigation Tab Under Another Component in React Native?

I'm using react-navigation version 5, currently, I have a screen with Text and Button inside a View which placed at the top of the SafeAreaView, and I need to add TopTabNavigator just below the View.
Here's the code:
TimelineComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TimelineComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Timeline</Text>
</ScrollView>
);
}
}
export default TimelineComponent;
TrendingComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TrendingComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Trending</Text>
</ScrollView>
);
}
}
export default TrendingComponent;
TopNav.js
import React from 'react';
import {createMaterialTopTabNavigator} from '#react-navigation/material-top-tabs';
import TimelineComponent from '../TimelineComponent';
import TrendingComponent from '../TrendingComponent';
const Tab = createMaterialTopTabNavigator();
export function TopNav() {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
);
}
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingHorizontal: 22,
paddingTop: 6,
paddingVertical: 6,
},
top_nav: {
marginVertical: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<View style={{backgroundColor: 'white'}}>
<SafeAreaView>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<View style={styles.top_nav}>
<TopNav />
</View>
</SafeAreaView>
</View>
);
}
}
export default WallFragmentComponent;
In the WallFragmentComponent.js file, I have placed <TopNav /> inside a View, but it's not rendering when I run the project. Here's the screenshot:
screenshot
How am I able to add top navigation just under the Wall Text and New Post button? any help will be much appreciated.
Thank you,
Regards
This might help
// TopNav.js
const Tab = createMaterialTopTabNavigator();
const AppNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
)
}
export default AppNavigator;
WallFragmentComponent.js
import AppNavigator from './AppNavigator';
...........
const TopNav = createAppContainer(AppNavigator);
class WallFragmentComponent extends React.PureComponent {
......
render() {
return (
<View style={{backgroundColor: 'white'}}>
......
<TopNav />
......
</View>
);
}
}
You can also use react-native-scrollable-tab-view
Well, finally I have found the solution:
Change the first <View ... /> element into <SafeAreaView style={{flex: 1}} /> and then everything is working correctly.
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingStart: 22,
paddingEnd: 22,
paddingTop: 6,
paddingBottom: 6,
},
top_nav: {
marginTop: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
{' '}
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<TopNav />
</SafeAreaView>
);
}
}
export default WallFragmentComponent;
Screenshot
And that's it

Adding a DOM element with the press of a button in react native

I want to be able to add a <Text> element with the press of a button in react native
Is this possible to make ? and how can i do it ?
my code :
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button } from 'react-native'
export default class App extends Component {
onPress = () => {
//some script to add text
}
render() {
return (
<View style = { styles.container }>
<View style = { styles.ButtonContainer }>
//i want to add text here
<Button
onPress={this.onPress}
title="Add item"
color="#FB3640"
accessibilityLabel="Add item"
containerViewStyle={{width: '100%', marginLeft: 0}}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
backgroundColor: '#fff',
alignItems: 'center',
},
text: {
marginTop: 100,
},
ButtonContainer: {
margin: 20,
width: '90%',
}
});
Thank you !
You need to define a piece of state and initialized it with false. When the user presses the button you have to switch this piece of state to true. Have a look here for more information about the local state: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class
Something like that should work:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button } from 'react-native'
export default class App extends Component {
state = {
displayText: false
}
onPress = () => {
this.setState({ displayText: true });
}
render() {
return (
<View style = { styles.container }>
<View style = { styles.ButtonContainer }>
{displayText && <Text>This is my text</Text>}
<Button
onPress={this.onPress}
title="Add item"
color="#FB3640"
accessibilityLabel="Add item"
containerViewStyle={{width: '100%', marginLeft: 0}}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
backgroundColor: '#fff',
alignItems: 'center',
},
text: {
marginTop: 100,
},
ButtonContainer: {
margin: 20,
width: '90%',
}
});

undefined is not an object (evaluating 'this.props.navigation')

I'm trying to create a React Native app with some basic routing.
This is my code so far:
App.js:
import React from 'react'
import { StackNavigator } from 'react-navigation'
import MainScreen from './classes/MainScreen'
const AppNavigator = StackNavigator(
{
Index: {
screen: MainScreen,
},
},
{
initialRouteName: 'Index',
headerMode: 'none'
}
);
export default () => <AppNavigator />
MainScreen.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity, Image } from 'react-native'
import HomeButton from './HomeButton'
export default class MainScreen extends Component {
static navigatorOptions = {
title: 'MyApp'
}
constructor(props) {
super(props)
}
render() {
return (
<View style={styles.container}>
<Image source={require('../img/logo.png')} style={{marginBottom: 20}} />
<HomeButton text='Try me out' classType='first' />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
HomeButton.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native'
import { StackNavigator } from 'react-navigation'
export default class HomeButton extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
}
var Dimensions = require('Dimensions')
var windowWidth = Dimensions.get('window').width;
const baseStyle = StyleSheet.create({
buttons: {
backgroundColor: '#ccc',
borderRadius: 2,
width: windowWidth * 0.8,
height: 50,
shadowOffset: {width: 0, height: 2 },
shadowOpacity: 0.26,
shadowRadius: 5,
shadowColor: '#000000',
marginTop: 5,
marginBottom: 5
},
buttonsText: {
fontSize: 20,
lineHeight: 50,
textAlign: 'center',
color: '#fff'
}
})
const styles = {
first: StyleSheet.create({
style: { backgroundColor: '#4caf50' }
})
}
Everything works fine, but when pressing the button I get
Can't find variable: navigate
I've read that I have to declare it like this:
const { navigate } = this.props.navigation
So I edited HomeButton.js and added that line at the beginning of the render function:
render() {
const { navigate } = this.props.navigation
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
Now I get:
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
It seems that the navigation object is not coming into the properties, but I don't understand where should I get it from.
What am I missing here?
React-navigation pass navigation prop to the screen components defined in the stack navigator.
So in your case, MainScreen can access this.props.navigation but HomeButton can't.
It should work if you pass navigation prop from MainScreen to HomeButton :
<HomeButton text='Try me out' classType='first' navigation={this.props.navigation}/>
Edit: You have to define the Homescreen in your stack navigator in order to navigate to it, your onPress={() => navigate('Home')} won't work until then.

Why won't <TextInput/> display what's being typed?

Whenever I click on Email in the first <TextInput/> box on my physical device, I can't see what's being typed. Only when I press Next to go to the Password box do I see what was typed in the Email box. Why's this so?
Here's App.js:
import React, {Component} from 'react';
import {View, StyleSheet} from 'react-native';
import BackGround from './components/BackGround';
export default class App extends Component {
render() {
return(
<View style={styles.back}>
<BackGround/>
</View>
);
}
}
const styles = StyleSheet.create({
back: {
flex: 1
}
});
Here's Login.js:
import React, {Component} from 'react';
import {StyleSheet, TextInput, View, Text, TouchableOpacity, KeyboardAvoidingView} from 'react-native';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}
updateTextInput = text => this.setState({text});
render() {
return(
<KeyboardAvoidingView behavior={"padding"} style={styles.container}>
<View>
<TextInput
style={styles.input}
returnKeyType={"next"}
keyboardType={"email-address"}
autoCorrect={false}
onChangeText={this.updateTextInput}
value={this.state.text}
/>
<TextInput
style={styles.input}
returnKeyType={"go"}
secureTextEntry
/>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Login</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Create Account</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
padding: 20
},
input: {
backgroundColor: '#DAE5FF',
paddingBottom: 20,
padding: 20,
paddingHorizontal: 15,
marginBottom: 10,
borderRadius: 15,
},
loginAndCA: {
fontSize: 40,
textAlign: 'center',
color: 'white',
fontFamily: 'Bodoni 72 Smallcaps',
paddingHorizontal: 10
},
buttons: {
paddingBottom: 50
}
});
export default Login;
Here's BackGround.js:
import React, {Component} from 'react';
import {StyleSheet, Image, View} from 'react-native';
import Login from './Login';
export default class BackGround extends Component {
render() {
return(
<View style={styles.first}>
<Image style={styles.container} source={require('../pictures/smoke.jpg')}>
<View style={styles.second}>
<Login/>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: null,
height: null,
backgroundColor: 'rgba(0,0,0,0)',
resizeMode: 'cover'
},
first: {
flex: 1
},
second: {
paddingTop: 290 // Moves both <TextInput> boxes down.
}
});
You need to pass value and onTextChange props to TextInput.
https://facebook.github.io/react-native/docs/textinput.html
You need to give it a value connected to state and as that textinput changes, you update the state value:
export default class TextInputExample extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}
updateTextInput = text => this.setState({ text })
render() {
return (
<View style={{ flex: 1}}>
<TextInput
style={{height: 40}}
placeholder="Type here!"
onChangeText={this.updateTextInput}
value={this.state.text}
/>
</View>
);
}
}

Pass data from one js to another js file React native

I am trying with react native , I have studied about it and now I am trying to learn it , This is my first day in this , I got some hints that how does it work form bellow mentioned tutorial.
https://www.tutorialspoint.com/react_native/react_native_text_input.htm
I am just trying with login page and handling the submit button click, just want to capture input data and want to app it to my Button.js file.
I know it may looks silly to you all there, but I really want to know it , I studied about props and was trying to use that in the same but when I replace component with props I start getting red screen , Please guide me little on this that if in case we are having two different components then how do we can pass our data between them.
Here I am posting both of the JS files :-
Form.js
import React, { Component, PropTypes } from 'react';
import Dimensions from 'Dimensions';
import {
StyleSheet,
KeyboardAvoidingView,
View,
ActivityIndicator,
TouchableOpacity,
Image,
} from 'react-native';
import UserInput from './UserInput';
import ButtonSubmit from './ButtonSubmit';
import SignupSection from './SignupSection';
import usernameImg from '../images/username.png';
import passwordImg from '../images/password.png';
import eyeImg from '../images/eye_black.png';
export default class Form extends Component {
constructor(props) {
super(props);
this.state = {
showPass: true,
press: false,
username: '',
password: ''
};
this.showPass = this.showPass.bind(this);
this.handleChange = this.handleChange.bind(this);
}
showPass() {
this.state.press === false ? this.setState({ showPass: false, press: true }) :this.setState({ showPass: true, press: false });
}
handleChange(event) {
// this.setState({usernamevalue: event.target.usernamevalue , passwordvalue : event.target.passwordvalue });
alert('A name was submitted: ' + this.state.password);
}
render() {
return (
<KeyboardAvoidingView behavior='padding'
style={styles.container}>
<UserInput source={usernameImg}
placeholder='Username'
autoCapitalize={'none'}
returnKeyType={'done'}
value={this.state.username}
onChangeText={(text) => this.setState({username:text})}
autoCorrect={false} />
<UserInput source={passwordImg}
secureTextEntry={this.state.showPass}
placeholder='Password'
returnKeyType={'done'}
value={this.state.password}
onChangeText={(text) => this.setState({password:text})}
autoCapitalize={'none'}
autoCorrect={false} />
<TouchableOpacity
activeOpacity={0.7}
style={styles.btnEye}
onPress={this.handleChange}
>
<Image source={eyeImg} style={styles.iconEye} />
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
}
const DEVICE_WIDTH = Dimensions.get('window').width;
const DEVICE_HEIGHT = Dimensions.get('window').height;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
},
btnEye: {
position: 'absolute',
top: 55,
right: 28,
},
iconEye: {
width: 25,
height: 25,
tintColor: 'rgba(0,0,0,0.2)',
},
});
ButtonSubmit.JS
import React, { Component, PropTypes } from 'react';
import Dimensions from 'Dimensions';
import {
StyleSheet,
TouchableOpacity,
Text,
Animated,
Easing,
Image,
Alert,
View,
} from 'react-native';
import { Actions, ActionConst } from 'react-native-router-flux';
import spinner from '../images/loading.gif';
const DEVICE_WIDTH = Dimensions.get('window').width;
const DEVICE_HEIGHT = Dimensions.get('window').height;
const MARGIN = 40;
export default class ButtonSubmit extends Component {
constructor() {
super();
this.state = {
isLoading: false,
};
this.buttonAnimated = new Animated.Value(0);
this.growAnimated = new Animated.Value(0);
this._onPress = this._onPress.bind(this);
}
_onPress() {
if (this.state.isLoading) return;
this.setState({ isLoading: true });
Animated.timing(
this.buttonAnimated,
{
toValue: 1,
duration: 200,
easing: Easing.linear
}
).start();
setTimeout(() => {
this._onGrow();
}, 2000);
setTimeout(() => {
Actions.secondScreen();
this.setState({ isLoading: false });
this.buttonAnimated.setValue(0);
this.growAnimated.setValue(0);
}, 2300);
}
_onGrow() {
Animated.timing(
this.growAnimated,
{
toValue: 1,
duration: 200,
easing: Easing.linear
}
).start();
}
render() {
const changeWidth = this.buttonAnimated.interpolate({
inputRange: [0, 1],
outputRange: [DEVICE_WIDTH - MARGIN, MARGIN]
});
const changeScale = this.growAnimated.interpolate({
inputRange: [0, 1],
outputRange: [1, MARGIN]
});
return (
<View style={styles.container}>
<Animated.View style={{width: changeWidth}}>
<TouchableOpacity style={styles.button}
onPress={this._onPress}
activeOpacity={1} >
{this.state.isLoading ?
<Image source={spinner} style={styles.image} />
:
<Text style={styles.text}>LOGIN</Text>
}
</TouchableOpacity>
<Animated.View style={[ styles.circle, {transform: [{scale: changeScale}]} ]} />
</Animated.View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
top: -95,
alignItems: 'center',
justifyContent: 'flex-start',
},
button: {
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#F035E0',
height: MARGIN,
borderRadius: 20,
zIndex: 100,
},
circle: {
height: MARGIN,
width: MARGIN,
marginTop: -MARGIN,
borderWidth: 1,
borderColor: '#F035E0',
borderRadius: 100,
alignSelf: 'center',
zIndex: 99,
backgroundColor: '#F035E0',
},
text: {
color: 'white',
backgroundColor: 'transparent',
},
image: {
width: 24,
height: 24,
},
});
Should I use something like this.props.state.username to pass data to SubmitButton.js file.
The above code is from :- https://github.com/dwicao/react-native-login-screen
I am playing with this demo to understand the flow and concepts, Please provide me some suggestions here.
Your little help would be very much appreciated
Regards.

Categories