React native material dropdown - How to render the text based on dropdown value - react-native

Hi I'm new to react native. I'm using react-native-material-dropdown.I want to change the text content based on the drop down value. By default my text content is empty and dropdown value also empty. When onChangeText function is triggers the text content should change based on selected drop down value.

Please post some of your code to get more accurate answers.
Meanwhile, please checkout the example code below with Dropdown example. Take a notice that dropdown's value is set to selectedCity value={this.state.selectedCity} and it is the same value manipulated when onChangeText triggers this.setState
import React from 'react';
import { View, Text } from 'react-native';
import { Dropdown } from 'react-native-material-dropdown';
export default class DropDownEx extends React.Component {
constructor(props) {
super(props);
this.state = {
cityData: [{
value: 'City1',
id: '123',
otherData: 'descr1'
}, {
value: 'City2',
id: '234',
otherData: 'descr2'
}, {
value: 'City3',
id: '345',
otherData: 'descr3'
}],
selectedCity: ""
};
}
render() {
return (
<Dropdown
label='City'
data={this.state.cityData}
value={this.state.selectedCity}
containerStyle={{borderColor: "gray", borderWidth: 0.5, borderRadius: 5, height: 50}}
inputContainerStyle={{ borderBottomColor: 'transparent', paddingTop: 10, paddingLeft: 10 }}
onChangeText={(city) => this.setState({selectedCity: city})}
/>
)}
}

Related

Is it possible to Get 'style' property values from React Native Element AFTER rendering using useRef?

I'm trying to dynamically apply margin & padding to a View, based on a ref'd TextInput's borderRadius. I am new to React coming from Xamarin where this type of thing is common.
I'm not sure if I have the correct approach, but I have seen some examples of people deriving style values from useRef.
Here is my custom LabelInput component:
import React, {useState} from 'react';
import {
View,
Animated,
StyleSheet,
ViewProps,
} from 'react-native';
import {Colors} from '../../../resources/colors';
import Text from './Text';
import TextInput from './TextInput';
import {TextInputProps} from 'react-native/Libraries/Components/TextInput/TextInput';
import {isNullOrWhiteSpace} from '../../../utils/stringMethods';
import {TextProps} from 'react-native/Libraries/Text/Text';
interface LabeledInputProps {
label: string;
error: string;
onChangeText: (text: string) => void;
placeholder?: string;
inputValue: string;
mask?: (text: string) => string;
validator?: (text: string) => string;
onValidate?: (value: string) => void;
viewProps?: ViewProps;
textProps?: TextProps;
errorTextProps?: TextProps;
inputProps?: TextInputProps;
}
export default function LabeledInput(props: LabeledInputProps) {
const inputRef = React.useRef<any>(null);
const [dynamicStyle, setDynamicStyle] = useState(StyleSheet.create({
dynamicContainer:{
marginHorizonal: 0,
paddingHorizonal: 0,
}
}));
const changeTextHandler = (inputText: string) => {
const displayText = props?.mask ? props.mask(inputText) : inputText;
props.onChangeText(displayText);
// ultimately not the exact behavior I'm after, but this is a simple example.
var test = inputRef.current.props.style;
// props.style always returns undefined,
// there doesn't appear to be a 'props' property on the 'current' object when debugging.
setDynamicStyle(StyleSheet.create({
dynamicContainer:{
marginHorizonal: test.borderRadius, // I want the padding/margin of this element to be
paddingHorizonal: test.borderRadius,// dynamically set based on the inputRef's borderRadius
}
}))
};
return (
<View
{...props.viewProps}
style={[
props.viewProps?.style,
localStyles.container,
]}>
<TextInput
ref={inputRef}
{...props.inputProps}
placeholder={props.placeholder}
style={localStyles.input}
onChangeText={changeTextHandler}
value={props.inputValue}
/>
<Animated.View
pointerEvents={'none'}>
<Text
{...props.textProps}
style={[props.textProps?.style, animatedStyles.label]}>
{props.label}
</Text>
</Animated.View>
{/* {stuff} */}
</View>
);
}
const localStyles = StyleSheet.create({
container: {
backgroundColor: 'blue',
justifyContent: 'flex-start',
flex: 1,
},
label: {
fontWeight: 'bold',
marginBottom: 8,
},
input: {
padding: 8,
},
error: {
backgroundColor: 'pink',
fontSize: 12,
paddingHorizontal: 8,
color: Colors.danger,
marginTop: 4,
},
});
const animatedStyles = StyleSheet.create({
label: {
fontSize: 16,
fontWeight: 'normal',
},
});
Here is my custom LabelInput component with forwardRef() implemented:
import React, {ForwardedRef, forwardRef} from 'react';
import {TextInput as NativeTextInput, TextInputProps} from 'react-native';
import {useGlobalStyles} from '../../../resources/styles';
const TextInput = (
props: TextInputProps,
ref: ForwardedRef<NativeTextInput>,
) => {
const styles = useGlobalStyles();
return (
<NativeTextInput
{...props}
ref={ref}
style={[styles.textInput, props.style]}
placeholderTextColor={styles.textInput.borderColor}
onChangeText={(text: string) => {
if (props.onChangeText) {
props.onChangeText(text);
}
}}
/>
);
};
export default forwardRef(TextInput);
I've tried referencing inputRef from different hooks, like useCallback & useEffect.
var test = inputRef.current.props.style; always returns undefined. And there doesn't appear to be a 'props' property on the 'current' object when debugging.
The link you mentioned contains two files with inputRef. Since inputRef is in parent component and use ref prop to pass inputRef, this will not work. ref is not available as prop. If you still want to use ref as prop, then use forward ref in child component as access the ref as second argument or you can use any other prop name to pass ref i.e. innerRef. You can read more in react documentation. Forward Refs
According to the code you attach in code sandbox, i think you are trying to access input styles in two components: App and LabeledInput. You should use one ref in main component and use it in LabelInput component. If you still want to have separate refs then you can ref callback function and attach the node with both refs.
const attachRef = (node: NativeTextInput) => {
inputRef.current = node;
ref.current = node;
};
return <TextInput ref={attachRef} />;
The correct type for inputRef.current is TextInputProps.
const inputRef = useRef() as MutableRefObject<TextInputProps>;
I have updated the code sandbox. I was able to access input field styles in both components. Hope this solves your problem.

Warning: Failed prop type: Invalid prop `textStyle` of type `array` supplied to `Cell`, expected `object`

this is my code which going to create a table, it is working well but every time its showing me the (Warning: Failed prop type: Invalid prop textStyle of type array supplied to Cell, expected object.) warning!! what should i do for that?
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { Table, Row, Rows } from 'react-native-table-component';
export default class ExampleOne extends Component {
constructor(props) {
super(props);
this.state = {
tableHead: ['Head', 'Head2', 'Head3', 'Head4'],
tableData: [
['1', '2', '3', '4'],
['a', 'b', 'c', 'd'],
['1', '2', '3', '456\n789'],
['a', 'b', 'c', 'd']
]
}
}
render() {
const state = this.state;
return (
<View style={styles.container}>
<Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff'}}>
<Row data={state.tableHead} style={styles.head} textStyle={styles.text}/>
<Rows data={state.tableData} textStyle={styles.text}/>
</Table>
</View>
)
}
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#fff' },
head: { height: 40, backgroundColor: '#f1f8ff' },
text: { margin: 6 }
});
This is an odd one because the documentation itself for react-native-table-component uses the text-style prop in the same way you do. There is an open issue reporting the same thing which may help you? https://github.com/Gil2015/react-native-table-component/issues/145
Additionally, if you want to just suppress the warning, in your app.js you can import Logbox from react-native and add: LogBox.ignoreLogs(['Invalid prop textStyle of type array supplied to Cell']);
react-native-table-component isn't being maintained by its original developer. Warnings like this are covered in the repo's issues section, and there are great forks that fix some errors. The link from #P.Brew led me to finding a dirty fix:
Replace line 29 in rows.js:
<Cell
...
// textStyle={[cellTextStyle && cellTextStyle(item), textStyle]} // built-in, replace or edit
textStyle={textStyle} // replace with this
...
/>
This fix only works if you don't plan to use cellTextStyle. There are other options in the issue for this warning if this doesn't work.

TypeError:Super expression must either be null or a function

getting error while making the below page, give me solution for this!!
import React, { Component } from 'react';
import { Text,View ,StyleSheet, TextInput, Button} from 'react-native';
import ValidationComponent from '../index';
export default class Register extends ValidationComponent {
constructor(props) {
super(props);
this.state = {First_name : "First Name",Last_name : 'Last Name', email: "tibtib#gmail.com", password:"****", confirm_password : '****' };
}
I think you've just become a bit confused about passing the variables around. As per our convo in the comments, here's my attempt at what I think you're trying to do (with explanations):
import React, { Component } from 'react';
import { Text, View, StyleSheet, TextInput } from 'react-native';
export default class Register extends Component {
constructor(props) {
super(props);
this.state = {
firstName: { // I have split this so you can store the value and a valid flag conveniently
value: '', // removed initial value and used a placeholder in the element instead
isValid: false
},
lastName: '',
email: 'tibtib#gmail.com',
password: '****',
confirmPassword: '****'
};
}
checkIfValid = (type, value) => { // you can add more checks to this as you add more fields
if (type == 'firstName') return value.length >= 4;
}
_onChangeText = (type, value) => {
// console.log('value =>', value);
const isValid = this.checkIfValid(type, value) // check validity whenever new text is entered
this.setState({ // removed the switch statement and just setState with the isValid variable above
[type]: {
value,
isValid
}
})
};
firstInputStyle = () => { // so we can change the style dynamically depending on state
if (!this.state.firstName.isValid) return styles.firstNameTextInput;
return [styles.firstNameTextInput, styles.isValid]; // if valid, add the isValid style
// you could also generalise this method to work on all input fields
};
render() {
return (
<View style={styles.container}>
<TextInput
style={this.firstInputStyle()} // here we get the style dynamically with the method above
onChangeText={value => this._onChangeText('firstName', value)}
value={this.state.firstName.value} // need to tie the value to our state
placeholder='Enter first name...'
/>
<Text>First name valid = {this.state.firstName.isValid.toString()}</Text>
</View>
);
}
}
const styles = StyleSheet.create({ // some dummy styles I made up
container: {
padding: 20,
paddingTop: 30,
height: '100%'
},
firstNameTextInput: {
borderColor: 'black',
borderWidth: 1,
fontSize: 25,
padding: 10
},
isValid: {
backgroundColor: 'green'
}
});
I hope that make sense... let me know if you have questions!
Note: I've also updated some of your variable names to camelCase as this is more conventional

how to pass form data from screen1 to screen2 in react native?

how to pass form data from screen1 to screen2 in react native ? I have following code in scrren1 I want posted amount data in screen2. Please let me know how can I pass data on screen2 and receive it in react native?
import React, { Component } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import t from 'tcomb-form-native'; // 0.6.9
const Form = t.form.Form;
const User = t.struct({
amount: t.String,
});
const formStyles = {
...Form.stylesheet,
formGroup: {
normal: {
marginBottom: 10
},
},
controlLabel: {
normal: {
color: 'blue',
fontSize: 18,
marginBottom: 7,
fontWeight: '600'
},
// the style applied when a validation error occours
error: {
color: 'red',
fontSize: 18,
marginBottom: 7,
fontWeight: '600'
}
}
}
const options = {
fields: {
amount: {
label: "Enter Amount You want to Top up",
error: 'Please add amount to proceed ahead!'
},
},
stylesheet: formStyles,
};
class HomeScreen extends Component {
static navigationOptions = {
title: 'Home',
};
handleSubmit = () => {
const value = this._form.getValue();
console.log('value: ', value);
}
render() {
return (
<View style={styles.container}>
<Form
ref={c => this._form = c}
type={User}
options={options}
/>
<Button
title="Pay Now"
onPress={this.handleSubmit}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
marginTop: 50,
padding: 20,
backgroundColor: '#ffffff',
},
});
export default HomeScreen;
It depends if you want to pass data between Parent to Child, Child to Parent or Between Siblingsā€Š
I suggest you to read Passing Data Between React Components, old but this article did help me to understand the logic behind passing data as it's not as easy to implement as in other programming languages.
Excerpt using props:
class App extends React.Component {
render() {
[... somewhere in here I define a variable listName
which I think will be useful as data in my ToDoList component...]
return (
<div>
<InputBar/>
<ToDoList listNameFromParent={listName}/>
</div>
);
}
}
Now in the ToDoList component, use this.props.listNameFromParent to access that data.
You have many ways to send informations from one screen to another in React Native.
eg.
Use React Navigation to navigate between your scenes. You will be able to pass params to your components, which will be accessible in the navigation props when received.
this.props.navigation.navigate({routeName:'sceneOne', params:{name} });
You can also send directly props to a component, and treat them in it. In your render section of your first component, you could have something like this :
<myComponent oneProps={name}/>
In that example, you will receive the props "oneProps" in your second component and you will be able to access it that way :
type Props = {
oneProps: string,
}
class myComponent extends React.Component<Props> {
render() {
console.log('received sent props', oneProps);
return (
<View> // display it
<Text>{this.props.oneProps}</Text>
</View>
);
};
}
These are only two effective solutions, but there are a lot more.
Hope it helped you :)
Have a good day

React native use propType from native component

I have CustomText component that accepts align as one of the props.
const alignPropType = PropTypes.oneOf(
['auto' /*default*/, 'left', 'right', 'center', 'justify']
)
CustomText.proptypes = {
align: alignPropType
}
Native Text Component has following propType validator for textAlign
PropTypes.oneOf(
['auto' /*default*/, 'left', 'right', 'center', 'justify']
)
So I want use textAlign propType from native Text component for CustomText Component.
That will look something like this:
CustomText.proptypes = {
align:Text.propTypes.style.textAlign
}
If i understand your question well, your component will be like this:
export default class CustomText extends Component {
render() {
return (
<Text textAlign={this.props.align}></Text>
);
}
}
CustomText.proptypes = {
align: propTypes.oneOf(['auto' , 'left', 'right', 'center', 'justify'])
}