Understanding textInput and navigating the documentation - react-native

three questions:
1) if you have multiple textInput fields how do you determine which one is being used?
2) with both onchangeText and onsubmitEditing what is being returned to the function
onSubmitEditing={()=>{this.clearText()}}
onChangeText={(text) => {this.captureInput(text)}}
I get that in onChangeText() text gives me the value in the input field. Are there any other parameters being passed back to that function?
Also, in onsubmitEditing() how do I access the event parameters being passed to clearText()?
I've read the documentation found here DOCS but it doesn't answer my question
3) Where in the documentation do you find these answers?

1) You just call different handlers to handle them separately:
<TextInput onChangeText={text => this.handleFirstInput(text)} />
<TextInput onChangeText={text => this.handleSecondInput(text)} />
2) There's no other parameters passed to them. What else do you need? You can set a ref on them but avoid that if possible.

Related

How to give alert message when InputText is empty and submitted?

I use react native and TextInput.
And if user submits inputText with empty value, I want to give them a message 'please write a comment'.
So I make a register module from useForm with required function.
It seems it prevents empty value created correctly, but alert message is not shown.
<WritingText
{...register("comments", { required: "댓글을 적어주세요." })}
placeholder="댓글을 입력하세요"
onChangeText={(text) => setValue("comments", text)}
onSubmitEditing={handleSubmit(onValid)}
></WritingText>
You can do it using formik, if you don't want to use it, you can try the onBlur callback where you can check your text length and then show an alert.
<WritingText
{...register("comments", { required: "댓글을 적어주세요." })}
placeholder="댓글을 입력하세요"
onChangeText={(text) => setValue("comments", text)}
onSubmitEditing={handleSubmit(onValid)}
onBlur={handleBlur}
></WritingText>

onChangeText of TextInput is updating state but retrieving the old value

I have a state:
const [userName, setUserName] = useState('');
Next, I have the TextInput as:
<TextInput style={styles.value}
keyboardType={'default'}
placeholder={'Your Name'}
value={userName}
editable={true}
onChangeText={(value) => {
setUserName(value)
}} />
The on a button's onPress event I'm calling this function:
function saveButtonPressed() {
alert("The Value of Name is " + userName);
}
The problem is I can see the vvalue getting updated in the text field, but in the alert I still see '' and if I save tthe coe again the second time it shows the updated value.
The reason they don't show the current value has to do with your functions forming closures. Even if the value of userName changes, it is still a const and since the function where this was updated still has scope in the 1st re-render the updated value wont show. Instead when the scope changes outside the closure thats when you get the updated value in the 2nd re-render.
The first link has solutions for this.
The second link has a bit more information about hooks.
These should answer your question in detail. https://stackoverflow.com/a/58877875/9745240 https://stackoverflow.com/a/54069332/9745240
And a read about closures should help you.

loop and get all TextInput value in a component/screen

I know that the practice of react native is to use onChangeText for change value as follow.
<TextInput
onChangeText = {(text)=> this.setState({myText: text})}
value = {this.state.myText}
/>
However, I wonder if i could do something like this. To summarise, I want to loop through all the TextInput and get the ref and value. I just want to do things in javascript way as follow. Is that possible to be done?
<TextInput id="id1" ref={ref => (this.remark = ref)} />
<TextInput id="id2" ref={ref => (this.remark1 = ref)} />
onSubmit = () => {
forEach(TextInput in component) {
console.log(TextInput.id) <- note id is custom property
console.log(TextInput.refName)
console.log(TextInput.value)
}
}
Yes, but I wouldn't recommend this approach. You could simply create an array of refs and loop through it in your onSubmit function.
forEach(TextInput in component) {
This is not possible in any javascript environment (not only because forEach and for..in syntax is different but also you can't expect to be able to loop over component elements by type (?) and get them)
What you want to do is not javascript way but old style browser way:
there are no ids in react-native
technically you could get uncontrolled TextInput's value like you would do in plain react in browser environment (via this.textInputRef._lastNativeText) but it's discouraged in react-native, most likely because because instead of DOM react native has to render to native views which all differ depending on the platform (iOS, Android, Windows, etc) but have to work the same
So it's not only impossible in react native but in plain react as well. It looks to me like you want to create a form, and sooner or later you will find out that you want validation or transformation on your inputs and switch back to controlled components anyway

ArrayInput with SimpleFormIterator and conditional inputs

Let's say I have the following array in my create form
const CreateDefaults = {Inputs: [{id: "ID1", param: "a"},{id: "ID2", param: "b"}]};
and then I want to show extra TextInput only when id==="ID2"
export const MyCreate = withStyles(myStyles)(({ classes, ...props }) => (
<Create {...props}>
<SimpleForm defaultValue={CreateDefaults}>
<ArrayInput source="Inputs" {...props}>
<SimpleFormIterator {...props}>
<DisabledInput source="id" />
{/*this does not work*/}
{this.id === "ID2" ? (<TextInput source="ParamValue"/>) :null}
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Create>
));
How can I do something like that? I know that for the whole form, one can use FormDataConsumer. However, what can one do inside ArrayInput/SimpleFormIterator for each iteration?
How to access current object in iteration? I tried something like the answer given to the 'Custom Input do not receive record when inside ArrayInput' issue in the react-admin github page, but it still does not receive the record in custom input.
From the latest documentation here, you can see that if you use FormDataConsumer that is within an ArrayInput, you have a parameter called scopedFormData that you can use to get the current record and dereference that to get whatever fields you need. It usually also goes hand in hand with the getSource function you can use when setting the source within your FormDataConsumer.

How to clear input in SlideTextInput (custom TextInput component)?

and of course sorry if the question is somewhat dumb.
In the app I'm developing a user should be able to swipe on the TextInput. Since TextInput only listens to taps I used this gist: https://gist.github.com/MikeShi42/87b65984f0a31e38d553cc056fcda017
(BTW #Michael Shi thanks a ton)
However, once I changed TextInput to SlideTextInput the Clear button ceased to work.
clearInput() {
this.setState({text: ''});
}
render() {
return (
<Button name='clear' action={this.clearInput} />
<SlideTextInput
style={styles.input}
ref='input'
onChangeText={(text) => this.setState({text: text})}
placeholder={this.state.placeholder}
value={this.state.text}
multiline={true}
returnKeyType='done'
blurOnSubmit={true} />
)
}
I also tried this.refs.input.setNativeProps({text: ''}); instead of just passing a new value prop (that should be — and was — sufficient for normal TextInput), and calling forceUpdate(), but again to no avail. I don't see much changes in SlideTextInput.js compared to the original TextInput component, but I must be missing something that would explain such bad behaviour?
UPD: the answer was pretty simple in the end. Instead of linking the component to its native counterpart (ref={this._setNativeRef}) like original TextInput does, SlideTextInput has it ref'ed to a string (ref="input"). I changed it back and voila.
Looking at the code it seems that the value props is not being sent to the original TextInput. It is extending the TextInput but it is returning another component without sending the value prop.
Try:
this.refs.input.setText('');
The answer was pretty simple in the end. Instead of linking the component to its native counterpart (ref={this._setNativeRef}) like original TextInput does, SlideTextInput has it ref'ed to a string (ref="input") (it's not about props in my code it's about SlideTextInput.js file itself). I changed it back and voila.