How to pass Picker value to parent component in React Native - react-native

I have a child Picker and it should pass selected value to it's parent. Components are in different .js files if it's important.
How can I pass the states of selected items?
parent
<RegionPicker regions={this.props.navigation.state.params.regionsJSON}/>
child:
export default class RegionPicker extends Component {
constructor(props) {
super(props);
this.state = {
selected1: '1',
selected2: '1'
};
}
onValueChange1(value: string) {
this.setState({selected1: value},
()=>{ console.log('new',this.state.selected1)}
);
}
onValueChange2(value: string) {
this.setState({selected2: value},
()=>{ console.log('new',this.state.selected2)}
);
}
render() {
return (
<View>
<Form>
<Item inlineLabel>
<Label style={{fontSize:16}}>Region</Label>
<Picker
iosHeader="Select one"
mode="dropdown"
placeholder='...'
selectedValue={this.state.selected1}
onValueChange={this.onValueChange1.bind(this)}
>
{this.getRegions(this.props.regions).map((item, index) => {
return (<Picker.Item label={item} value={item} key={index}/>)
})}
</Picker>
</Item>
<Item inlineLabel last>
<Label style={{fontSize:16}}>Suburb</Label>
<Picker
iosHeader="Select one"
mode="dropdown"
placeholder='...'
selectedValue={this.state.selected2}
onValueChange={this.onValueChange2.bind(this)}
>
{this.getSuburbs(this.state.selected1).map((item, index) => {
return (<Picker.Item label={item} value={item} key={index}/>)
})}
</Picker>
</Item>
</Form>
</View>
);
}
}
I would appreciate for any help and ideas.

In your parent, create a function that will capture your RegionPicker value. In this example, myFunction.
myFunction = (value) => {
console.log(value);
}
Then pass down your function as a prop, like so:
<RegionPicker
regions={this.props.navigation.state.params.regionsJSON}
onChange={e => { this.myFunction(e) }}
/>
Inside of RegionPicker you can simply call your function within onValueChange1() and onValueChange2().
this.props.onChange(value);
You should also .bind() your functions within the constructor. So inside of your RegionPicker you can add
this.onValueChange1 = this.onValueChange1.bind(this);
this.onValueChange2 = this.onValueChange2.bind(this);
And then just call
this.onValueChange1 in your Picker's onValueChange function.

As i thing you can do one thing you can get the value in the parent component
onValueChange={()=>{this.props.onValueChange1()}}
And in the component you call this function so you will get value
<RegionPicker onValueChange1={()=>{this.calculate()}}/>
calling the function in parent state will be
calculate (value: string){
**Do you logic stuff here **
}
May you get the value now

Related

How can I pass a state from the parent view to the child?

MyPinchZoomView has a state 'scale'.
In the setup below, how can the component 'board' keep track of the current scale?
render() {
return (
<MyPinchZoomView
minScale={0.9}
maxScale={2}
>
{ this.board }
</MyPinchZoomView>
)
}
The same Question, if I would add the MyPinchZoomView within the board component:
return (
<View>
<MyPinchZoomView
minScale={0.9}
maxScale={2}
>
{ this.fields }
{ this.rackFields }
{ this.figures }
</MyPinchZoomView>
<Toolbar board={this} figures={this.figures}></Toolbar>
<Text>{this.state.lastRefresh}</Text>
<Moves game={this.props.game} lastRefresh={this.state.lastRefresh}/>
<FlashMessage position="top" ref="errorMessage" />
</View>
)
}
You can either pass scale as a function param, i.e. this.board(scale), or instead use the component as a child directly:
<Board
scale={scale}
/>
Rather passing complete states (not recommended)
Pass values as props
such as
<ParentComponent>
<ChildComponent dataOne={this.state.stateOfDataOne}/>
</ParentComponent>
then in your child component
<ChildComponent>
<Text>{this.props.dataOne}</Text>
</ChildComponent>

How do i call a function outside of Field render method in React-native?

Hi Experts i'm a newbie in react-native, help will appreciated.
I need to call a method name openModel() which is globally declared in Component and i have a method renderInput which renders each Input passed in Field tag. When openModel() is call inside renderInput of its Inputs on Focus. Error shows _this4.openModel is not a function. Its clearly understood that this is getting incremented because of multiple time renderInput method is called.
How do i fix this ?
Below is short code
class AddPatientForm extends Component {
constructor(props) {
super(props);
openModel = () => {
this.refs.bGroup.open();
}
renderInput({ input, label, type, meta: { touched, error, warning } }) {
return (
<View style={{ flexDirection: "row", height: 25, paddingRight: 5, }}>
<Input
ref={c => { this.textInput = c }}
returnKeyType={input.name === "Password" ? "" : "next"}
onSubmitEditing={() => { this.textInput._root.focus(); }}
blurOnSubmit={false}
secureTextEntry={input.name === "Password"}
{...input}
onFocus={() => this.openModel()}
keyboardType={input.name === "mobile" || input.name === "age" ? "numeric" : "default"}
autoCapitalize="none"
/>
</View>
);
}
<Field name="patientId" component={this.renderInput} type="" validate={[alphaNumeric,required]} />
}
you can simply write OpenModel() like this -
openModel() {
this.refs.bGroup.open();
}
Hope it works !
Please remove your openModel() function from constructor it will work for you if you define your function outside of constructor
openModel = () => {
this.refs.modal2.open();
}
you can call your function and define inside of class then directly using this.openModel();
if you have globally function and define outside of class then you don't need to use this keywords.

want to generate number through loop in multiple selector react native

hey guys I am using multiple selector in my app..the thing I want t show is that I want to generate num from 1 to 69 through loop..but when I tried to generate number by loop it gives me error like undefined is not a function ...
I tried a loop as globally and in my render function but every time I have same error...
export default class Createottery extends Component {
static navigationOptions = {
header: null
}
state = { selectedFruits: [],mynum:[] }
onSelectionsChange = (selectedFruits) => {
//alert(JSON.stringify(selectedFruits))
// selectedFruits is array of { label, value }
this.setState({ selectedFruits:selectedFruits })
alert(JSON.stringify(this.state.selectedFruits))
}
componentDidMount(){
for(let mylottery=0; mylottery<=69;mylottery++)
{
this.setState({mynum:mylottery})
//alert(mylottery)
}
}
render () {
let comeon=0
for(comeon=0;comeon<=5;comeon++){
comeon=comeon }
return (
<Container style={styles.Containerstyle}>
<Header searchBar rounded style={styles.headerstyle}>
<Item style={{backgroundColor:'#000'}}>
<Input placeholder="Lottery" placeholderttextSize={22} placeholderTextColor={'#fff'}/>
<Icon name="search" style={{color:'#fff'}} size={22}/>
</Item>
</Header>
<Content>
<View >
<Text style={{color:'#000',alignItems: 'center',fontSize:22}}>select any 5 number or quick pick</Text>
<SelectMultiple
style={{backgroundColor:'black'}}
items={comeon}
//selectedItems={this.state.selectedFruits}
// onSelectionsChange={this.onSelectionsChange}
/>
</View>
</Content>
</Container>
)
I want when my app starts It gives my all number which I want to generate through loop
1) Because you are sending number to items of SelectMultiple Component. items should be array of object.
<SelectMultiple
style={{backgroundColor:'black'}}
items={comeon} {//this should be array instead of number}
selectedItems={this.state.selectedFruits}
onSelectionsChange={this.onSelectionsChange}
/>
2) You are doing the same mistake while creating array in componentDidMount. You are setting every looped number to mynum

How to check checkbox when there is an array in React Native?

I want to get checked friends using checkbox. But I not quite sure how i will achieve it, hope someone can help me.
This is my state:
state = {checked: false}
This is where I want to map array
{this.props.navigation.getParam('friends').map((name, key) => (
<View>
<Text>{name}</Text>
<CheckBox
checked={this.state.checked}
onPress={(val)=>{}}
/>
</View>))}
Note: Or Could someone write me an app/code snippet in snack.expo.io how to get only checked checkbox value
You can write a custom checkbox component
export default class CustomCheckbox extends Component {
constructor(props) {
super(props);
this.state = {
checked: false,
};
}
toggleChange(){
this.setState({checked: !this.state.checked});
}
render() {
return (
<View>
<Text>{this.props.name}</Text>
<CheckBox
checked={this.state.checked}
onPress={() => this.bind.toggleChange(this)}
/>
</View>
);
}
}
and import your CustomCheckbox component
import CustomCheckbox from "your CustomCheckbox.js path"
{this.props.navigation.getParam('friends').map((name, key) => (
<View>
<CustomCheckbox name={name} />
</View>
))}
Your code is pretty good to go, you just need to update a bit. You have following two options:
Your friend's array should have checked key within each containing object, then you can simply do something like this.
{
this.props.navigation.getParam('friends').map((item, key) => (
let {name, checked} = item // item is an object from friends array,the and it have name, checked and other keys
<View>
<Text>{name}</Text>
<CheckBox
checked={checked}
onPress={(val)=>{}}
/>
</View>))
}
Other is you to save the name of the person as key and true/false as the checked state, eg :
toggleCurrentFirendState = (item)=>{
this.setState((prevState)=>{
let {name} = item //get name from clicked friend from the list
return {
...prevState, //used spread operator, so that other states doesn't get mutat.
[name]:!prevState[name] //toogle state of clicked item
}
})
}
//within your render
{
this.props.navigation.getParam('friends').map((item, key) => (
let {name} = item // item is an object from friends array,the and it have name, checked and other keys
<View>
<Text>{name}</Text>
<CheckBox
checked={name ===this.state[name]} //see change
onPress={(val)=>{this.toggleCurrentFirendState(item)}}
/>
</View>))
}

Update Input Value while mapping React Native

I am creating react-native mobile app. I have an array with some values. I want to set array's value into input field. I have added value in the fields but i can't able to update these values. I have set my values in a qty variable like this:
constructor(props) {
super(props);
this.state = {
qty:[],
}
}
componentWillMount() {
var ids = [];
this.props.data.map((dataImage,Index) => {
dataImage['pro-name'] != undefined && (
ids.push({'qty':dataImage['pro-qty']})
)
})
this.setState({qty:ids})
}
render() {
return {
this.props.data.map((dataImage,Index)=>(
<View key={Index} style={productStyle.cartview}>
{dataImage['pro-name'] && (
<View style={productStyle.cartmain}>
<Input value={this.state.qty[Index]['qty']} onChange={this.handleChangeInput.bind(this)} style={{width:40,height:40,textAlign:'left'}} />
</View>
)}
</View>
))
}
}
Its showing values properly into the input field but i can't able to type anything into the field to update the values. what can i do for this
I will suggest you to move your input container into separate class, its better approach and each component will handle its own state. Its easy to handle and will result better in performance too.
components = []
render() {
return this.props.data.map((item, index) => (
<CustomComponent data={item} index={index} ref={(ref) => this.components[index] = ref} />
))
}
You can then get child (CustomComponent) value from its ref.
this.components[index].getValue()
this.components[index].setValue('Value');
You will need to create these functions (getValue & setValue) in CustomComponent class.
solution
Here is solution to your query. You need to install lodash or find other solution to make a new copy qty.
<Input onChangeText={(text) => this.handleChangeText(text, index)} />
handleChangeText = (text, index) => {
const qty = _.cloneDeep(this.state.qty);
qty[index] = {
qty: text
}
this.setState({qty})
}
Your Input's value is set to this.state.qty[Index]['qty']. And to change it on text edit, you can do it like this. You do not need to bind the function, instead use an arrow function like this.
onChangeText={ (newValue) => {
this.setState({ <your-input-value-state>:newValue })
}}
You have to update the value of each Input individually on onChange event.
Replace your with Input with this
<Input value={this.state.qty[Index]['qty']}
onChange={this.handleChangeInput.bind(this, Index)}
style={{width:40,height:40,textAlign:'left'}}
/>
and update the state accordingly with the Index when the event is called
handleChangeInput(index, value){
let {qty} = this.state;
let qty_update = qty.slice();
qty_update[index]['qty'] = value;
this.setState({qty: qty_update});
}