I want to be able to retrieve the value of the text after the user presses enter/return.
I tried the following ...
class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
text:''
}
}
callTextSubmit = (val) => {
console.log('callTextSubmit ', val);
};
render() {
return (
<View>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({ text })}
onSubmitEditing={(text) => this.callTextSubmit(text)}
value={this.state.text}
/>
</View>
)
}
}
This returns the following... from the console log.
Proxy {dispatchConfig: {…}, _targetInst: FiberNode, isDefaultPrevented: ƒ, isPropagationStopped: ƒ, _dispatchListeners: ƒ, …}
>[[Handler]]:Object
>[[Target]]:Class
>[[IsRevoked]]:false
I want to access the value from the text input, is there a workaround to this? Thank you
The argument for the onSubmitEditing handler is the event, not the current input.
Since you set the state variable text each time the TextInput is changed, you can just use the text variable in your state instead.
callTextSubmit = () => {
console.log('callTextSubmit ', this.state.text);
};
Since you are using this line to add the TextInput's value to state
onChangeText={(text) => this.setState({ text })}
The reasonable way would be to get the value from state on your onPress function on a Button (TouchableOpacity/TouchableHighlight) added to your View like this:
<TouchableOpacity onPress={()=>console.log(this.state.text)}>
<Text>
Enter
</Text>
</TouchableOpacity>
Here is code for your Component
class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
text:''
}
}
callTextSubmit = () => {
console.log(console.log(this.state.text));
};
render() {
return (
<View>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
<TouchableOpacity onPress={()=>console.log(this.state.text)}>
<Text>
Enter
</Text>
</TouchableOpacity>
</View>
)
}
Related
Dynamically generate a TextInput when you press a button but I can’t get the value that the user digits,try to use states but I can’t because it’s not with the other general textInputs but it’s imported as Field.
try to create a state in the component file and move it to the general view and print it to see if it works and not...is there any way to bring this state?
general view:
import Campo from './campoInput';
constructor(props){
super(props);
this.state={
Cbusto:"",
Ccintura:"",
Ccadera:"",
valueArray: []
};
this.addNewEle = false;
}
agregarCampo=()=>{
this.addNewEle = true;
const newlyAddedValue = { text: 'prueba'};
this.setState({
valueArray: [...this.state.valueArray, newlyAddedValue]
});
}
render(){
return(
------Here are the normal textInput-----
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele} />;
})}
</View>
<View style={styles.flex}>
<View style={styles.ButtonAdd}>
<Button
title="Add input"
color="#B13682"
onPress={this.agregarCampo}
></Button>
</View>
)
}
Component:
constructor(props){
super(props);
this.state={
info:""
};
}
render(){
return(
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={(text) => this.setState({info:text})}></TextInput>
</View>
</View>
)
}
can be solved by adding the onChangeText event to the Field component in the overview and in the same way in the TextInput of the component being imported, using props status
General view:
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele}
onChangeText={(text) => this.setState({ info: text })}
/>;
})}
</View>
Component
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={this.props.onChangeText}></TextInput>
</View>
</View>
Here is my code for the slider:
class RedSlider extends React.Component {
constructor(props){
super(props)
this.state = {
percentage: 100,
minPercentage: 0,
maxPerentage: 100,
}
}
render() {
const {percentage} = this.state;
return (
<View>
<Slider
style={{ width: 300}}
step={1}
minimumValue={0}
maximumValue={100}
value={this.state.percentage}
thumbTintColor='black'
maximumTrackTintColor='rgba(255,0,0,1.0)'
minimumTrackTintColor='rgba(255,0,0,1.0)'
onValueChange={val => this.setState({ percentage: val })}
/>
<View style={styles.textCon}>
<Text style={styles.colorBlack}>{this.state.minPercentage}%</Text>
<Text style={styles.colorBlack}>
{this.state.percentage + '%'}
</Text>
<Text style={styles.colorBlack}>{this.state.maxPerentage}%</Text>
</View>
</View>
);
}
}
I reference the slider in a function that is a certain screen for my app. I can successfully display the slider and everything, so I am good on that front. I call the slider like so, within the return():
<RedSlider/>
However, how do I access the value of the slider within the screen function, so that I can actually use the slider. I just want to have that percentage value. Thank you.
You have made an example of an uncontrolled component so state is stored local to that component.
If you want to pass the value up to the parent you can have another onChange callback that passes the value higher.
class RedSlider extends React.Component {
constructor(props){
super(props)
this.state = {
percentage: 100,
minPercentage: 0,
maxPercentage: 100,
}
this.onChange = this.onChange.bind(this)
}
onChange (val) {
this.setState({ percentage: val })
props.onValueChange(val)
}
render() {
const {percentage} = this.state;
return (
<View>
<Slider
style={{ width: 300}}
step={1}
minimumValue={0}
maximumValue={100}
value={this.state.percentage}
thumbTintColor='black'
maximumTrackTintColor='rgba(255,0,0,1.0)'
minimumTrackTintColor='rgba(255,0,0,1.0)'
onValueChange={onChange}
/>
<View style={styles.textCon}>
<Text style={styles.colorBlack}>{this.state.minPercentage}%</Text>
<Text style={styles.colorBlack}>
{this.state.percentage + '%'}
</Text>
<Text style={styles.colorBlack}>{this.state.maxPercentage}%</Text>
</View>
</View>
);
}
}
However, it's generally better to minimize local state where unnecessary and use a controlled component and only store the component on the parent. This is because the component and parent's values can get out of sync.
class RedSlider extends React.Component {
constructor(props){
super(props)
this.state = {
minPercentage: 0,
maxPercentage: 100,
}
}
render() {
return (
<View>
<Slider
style={{ width: 300}}
step={1}
minimumValue={0}
maximumValue={100}
value={this.props.percentage} // get percentage directly from the parent.
thumbTintColor='black'
maximumTrackTintColor='rgba(255,0,0,1.0)'
minimumTrackTintColor='rgba(255,0,0,1.0)'
onValueChange={val => this.props.onValueChange({ percentage: val })} // send changes to the parent by passing a callback to this component
/>
<View style={styles.textCon}>
<Text style={styles.colorBlack}>{this.state.minPercentage}%</Text>
<Text style={styles.colorBlack}>
{this.state.percentage + '%'}
</Text>
<Text style={styles.colorBlack}>{this.state.maxPercentage}%</Text>
</View>
</View>
);
}
}
Checkout the react docs on controlled and uncontrolled components for more info.
This is a sample code i am trying to understand.
class Form extends React.Component {
constructor (props) {
super(props)
this.state = {
input: ''
}
}
handleChangeInput = (text) => {
this.setState({ input: text })
}
render () {
const { input } = this.state
return (
<View>
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={this.handleChangeInput}
value={input}
/>
</View>
)
}
}
In this the code that is troubling me is
onChangeText={this.handleChangeInput}
In this piece of code, there is no argument passed to the method(handleChangeInput) which expects text.
Can someone please throw a light here.
Basically you're passing a reference to a function that has the same signature.
React function reference may help shed some light.
given
callback = param => { /* do stuff */ };
then
componentFn={callback};
is equivalent to
componentFn = param => { /* do stuff */ };
but
componentFn={param => callback(param)}
is equivalent to
component = param => { callback(param) } // call function that does stuff
direct reference just removes a middle function binding.
Need to pass the text input to the handleChangeInput
<View>
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) =>{this.handleChangeInput(text)}} value={input}/>
</View>
or set directly the change text value
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({input:text})} value={input}/>
I have a parent class that passes a function called editClassInfo to a child class. This function, is bound to the parent, and when called, immutably changes the state of the parent. However, the parent does not render again, instead having to set the state from within the parent.
Specifically, the problem is with a modal component that has a textInput that, when the text is changed, sets the state of the parent screen. However, when the modal is closed, the screen's state does not update immediately, even though the state is changed. Instead, another this.setState() has to be called in order for the render to happen again.
Here is a picture reference of the problem:
https://imgur.com/a/oCHRTIu
Here is the code:
This is the parent component.
export default class Classes extends Component {
static navigationOptions = {
title: 'Classes'
};
constructor() {
super();
this.state = {
numObjects: 3.,
classes: [
{
className: "Math",
teacherName: "Someone",
},
{
className: "Science",
teacherName: "Someone",
},
{
className: "Art",
teacherName: "Someone",
}
]
};
this.editClassInfo = this.editClassInfo.bind(this);
}
editClassInfo(index, infoType, value) {
let newClass = this.state.classes;
switch (infoType) {
case 'className':
newClass[index].className = value;
break;
case 'teacherName':
newClass[index].teacherName = value;
break;
}
this.setState({classes: newClass});
}
addClass(name, name2) {
let newClass = this.state.classes.concat({className: name, teacherName: name2});
this.setState({classes: newClass});
}
loadClasses = () => {
this.setState({
numObjects: this.state.numObjects * 2,
})
}
render(){
const classData = this.state.classes;
console.log(this.state.classes[0]);
return (
<View style={styles.container}>
<TopBar title='Classes'/>
<View style={styles.classHeader}>
<Text style={styles.currentClasses}> CURRENT CLASSES </Text>
<TouchableOpacity onPress={() => {this.addClass('World History', 'Someone')}}>
<Image
style = {styles.addClass}
source={require('../resources/addClass.png')}
/>
</TouchableOpacity>
</View>
<FlatList
data = { classData }
onEndReached = {this.loadClasses}
keyExtractor = {(item, index) => index.toString()}
initialNumtoRender = {3}
renderItem = {({item}) =>
<ClassBox
index={this.state.classes.indexOf(item)}
editClassInfo ={this.editClassInfo}
className={item.className}
teacherName={item.teacherName}
/>
}
/>
</View>
);
}
}
I pass editClassInfo onto a component called ClassBox:
export default class ClassBox extends Component {
static propTypes = {
className: PropTypes.string.isRequired,
teacherName: PropTypes.string.isRequired,
index: PropTypes.number.isRequired
};
constructor(props) {
super(props);
this.state = {
isVisible: false,
};
this.modalVisible = this.modalVisible.bind(this);
}
modalVisible(visible) {
this.setState({isVisible: visible});
}
render(){
return(
<View>
<ClassEdit
index={this.props.index}
editClassInfo={this.props.editClassInfo}
isVisible={this.state.isVisible}
modalClose={this.modalVisible}
className={this.props.className}
teacherName={this.props.teacherName}
/>
<TouchableOpacity onPress={() => {this.modalVisible(true)}}>
<View style={styles.container}>
<Image
source={{uri: 'http://via.placeholder.com/50x50'}}
style={styles.classImage}
/>
<View style={styles.classInfo}>
<Text style={styles.className}>
{this.props.className}
</Text>
<Text style={styles.teacherName}>
{this.props.teacherName}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
)
}
}
This component contains the Child Modal ClassEdit:
export default class ClassEdit extends Component {
static propTypes = {
index: PropTypes.number.isRequired,
isVisible: PropTypes.bool.isRequired,
className: PropTypes.string.isRequired,
teacherName: PropTypes.string.isRequired
}
render() {
return(
<Modal
animationType="none"
transparent={false}
visible={this.props.isVisible}
>
<View style={styles.container}>
<View style={styles.closeTop}>
<TouchableOpacity onPress={() => {
this.props.modalClose(false);
}}>
<Image
style={styles.closeIcon}
source={require('../resources/close.png')}
/>
</TouchableOpacity>
</View>
<View style={styles.classInfo}>
<Image
source={{uri: 'http://via.placeholder.com/150x150'}}
style={styles.classImage}
/>
<TextInput
style={styles.className}
placeholder='Class Name'
value={this.props.className}
onChangeText = {(className) => {this.props.editClassInfo(this.props.index, 'className', className)}}
/>
<TextInput
style={styles.teacherName}
placeholder='Teacher Name'
value={this.props.teacherName}
onChangeText = {(teacherName) => {this.props.editClassInfo(this.props.index, 'teacherName', teacherName)}}
/>
</View>
</View>
</Modal>
);
}
}
It is in this last component called ClassEdit where the parent state gets changed, but when the modal is closed, the updated state is not seen, instead having to call addClass to trigger it.
I am a bit new to react-native so my code might not be the best, and the problem might be really simple, but any help would be appreciated.
let newClass = this.state.classes; creates a reference to the actual classes state, you're then mutating it.
To create a new array in an immutable way you can do this :
ES6 :
let newClass = [...this.state.classes];
ES5 :
let newClass = [].concat(this.state.classes);
In a a react native app I have some text and then a textinput rendered on the screen. I'm trying to figure out how to output the same text and the same textinput when I submit on in the original text field. I was thinking to do this recursively but I'm not sure how where and how implement the function to do so.
If it's in the same screen, than you can use local state. here's the example
class TestScreen extends Component {
constructor(props) {
super(props)
this. state = {
firstInput:'First Input',
secondInput:''
}
this.submit = this.submit.bind(this)
}
submit(){
this.setState({ secondInput: this.state.firstInput })
}
render() {
return (
<View style={{flex:1,marginTop:40}}>
<View>
<Text>Text Input #1</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text)=> this.setState({firstText:text})}
value={this.state.firstInput}
/>
<Button
onPress={this.submit}
title="Submit"
/>
</View>
<View style={{marginTop:20}}>
<Text>Text Input #1</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
value={this.state.secondInput}
/>
</View>
</View>
);
}
}
I hope that help. Thanks
Perhap you can use ref,state,conditional rendering. let's code talk
const MyInputs = (props) => {
inputs =props.inputs
result=inputs.map(function(value,index){
return(
<TextInput key={index} style={styles.input} value={value} />
)
})
return(
<View>
{result}
</View>
)
}
class TestScreen extends Component {
constructor(props) {
super(props)
this. state = {
inputs:[]
}
this.submit = this.submit.bind(this)
this.clearText = this.clearText.bind(this)
}
submit(){
let lastInput=this._textInput._lastNativeText
let inputs=this.state.inputs
this._textInput.setNativeProps({text: ''});
inputs.push(lastInput)
this.setState({
inputs:inputs
})
}
clearText = () => {
this.setState({
inputCount: this.state.inputCount + 1,
})
this._textInput.setNativeProps({text: ''});
}
render() {
return (
<View style={{flex:1,marginTop:40}}>
<View>
<Text>Text Input #1</Text>
<TextInput
style={styles.input}
ref={component => this._textInput = component}
/>
<Button onPress={this.submit} title="Submit"
/>
</View>
<MyInputs inputs={this.state.inputs}/>
</View>
);
}
}