简体   繁体   中英

How to pass 'State' from child to parent in 'React Native Functional Component'?

I have created a picker component to get data from API and display it(ProductNames) in the picker list, to select one of them. Then I able to get picker item value as a productID. After that, I use this child component in the parent component, which indicates a form to submit. Now I can see the picker in the parent component(form) and I can select one of them.

My main purpose is to open an input field through the picker. So now I need to pass the item.value ( as a state 'selectedValue') to parent component to submit. How can I pass this child state to parent state?

this is my child component:

import React, {useEffect, useState} from 'react';
import {View, StyleSheet} from 'react-native';
import {Picker} from '@react-native-picker/picker';
import AsyncStorage from '@react-native-community/async-storage';


const ProductPicker = () => {
    const [selectedValue, setSelectedValue] = useState('');
    const [productDetails, setproductDetails] = useState([]);
console.log('selected value', selectedValue);
    useEffect(() => {
        getProductList();
    }, []);

    const getProductList = async () => {
        const token = await AsyncStorage.getItem('userToken');
        

        fetch('http://10.0.2.2:3000/customer/get-all-products', {

            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authentication': `Bearer ${token}`,
            },
        })
            .then((response) => response.json())
            .then((json) => setproductDetails(json.data))
            .catch((error) => console.error(error));

    };

    return (
        <View style={styles.container}>
            <Picker
                selectedValue={selectedValue}
                style={{height: 40, width: 150}}
                onValueChange={(itemValue, itemIndex) => {
                    setSelectedValue(itemValue);
                }}
            >

     

                {productDetails.map((item, index) => {
                    return (
                        <Picker.Item label={item.productName} value={item.productID} key={index}/>);
                })}

            </Picker>

        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 40,
        alignItems: 'center',
    },
});

export default ProductPicker;

and this is my parent component:

import * as React from 'react';
import {Button, View, Text, ScrollView, StyleSheet, Alert} from 'react-native';
import {Appbar} from 'react-native-paper';
import {TextInput, HelperText} from 'react-native-paper';
import {useEffect, useState} from 'react';
import AsyncStorage from '@react-native-community/async-storage';
import ProductPicker from './ProductPicker';


const ComplaintSubmission = ({navigation}) => {

    const [productID , setproductID] = useState('');
    const [description , setdescription] = useState('');
    const [token, setToken] = useState('');
    


    const saveToken = async () => {
        const token = await AsyncStorage.getItem('userToken');
        console.log('token from storage', token);
        setToken(token);
    }

    useEffect(() => {
        saveToken();
        fetch("http://10.0.2.2:3000/customer/lodge-complaint", {

            method: "post",
            headers: {
                'Content-Type': 'application/json',
                'Authentication': `Bearer ${token}`
            },
            body: JSON.stringify({

                description : description,
            })

        })

    }, []);


    const openAlert = () => {
        Alert.alert(
            "Complaint Successfully Submitted",
            "We review it as soon as possible. Thank you for reaching for us!",
            [{
                text: "OK",
                onPress : () => navigation.navigate("DashboardDrawer" ),

            }]


        );
    }

  return (
    <ScrollView>
      <Appbar.Header>
        <Appbar.BackAction onPress={() => navigation.goBack()} />
        <Appbar.Content title="Submit Complaint" />
        <Appbar.Action icon="magnify" onPress={() => navigation.openDrawer()} />
      </Appbar.Header>
      <Text>Plese Fill the following</Text>
      <View>
         

       <ProductPicker />

        <HelperText type="info">
          Make sure select the correct Product
        </HelperText>
      </View>

      <TextInput
        style={styles.PIDstyle}
        label="Description"
        onChangeText = {(description) => setdescription(description)}
      />
      <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
        <Text>This is submittion</Text>
        <Button onPress={() => openAlert()} title="Submit Complaint" />
      </View>
    </ScrollView>
  );
};
export default ComplaintSubmission;
const styles = StyleSheet.create({
  PIDstyle: {
    marginTop: 30,
    marginLeft: 10,
    marginRight: 10,
  },
});

You don't want to pass the state from child to parent, you want to pass it from parent to child. You need to lift the state up to ComplaintSubmission and use props to control ProductPicker .

In ComplaintSubmission , call the ProductPicker with the current productId and a callback to update it.

<ProductPicker productID={productID} setproductID={setproductID} />

Now ProductPicker has these props. It should use them instead of the local state selectedValue which you can now delete.

const ProductPicker = ({productID, setproductID}) => {
<Picker
    selectedValue={productID}
    style={{height: 40, width: 150}}
    onValueChange={(itemValue, itemIndex) => {
        setproductID(itemValue);
    }}
>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM