0
votes

I am really new to React Native. My component was working fine with just 1 picker. However, after I added one more picker the code became complicated.

The data of the second picker depends on the selected value of first picker, since I put that value as a parameter on api url. I tried to write a function to trigger second picker every time the user changes the first picker's value. But now even my first picker's onValueChange does not work. Can you help me to find a right solution?

Code:

import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {
  StyleSheet,
  Text,
  View
} from 'react-native';

import {Picker} from '@react-native-picker/picker';


const VeriGuncelleme = ({route}) => {
    
    const { responseData } = route.params;
    const {kullaniciBilgisi} = route.params; 

    var bolge = responseData.items[0].bolge; 
    var etiket_no = responseData.items[0].etiket_no;
    var marka = responseData.items[0].uretici;
    var model = responseData.items[0].model;
    var serino = responseData.items[0].serino;
    var ad_soyad = responseData.items[0].ad_soyad;
    var varlik_turu = responseData.items[0].varlik_turu;


    const [selectedValueMarka, setSelectedValueMarka] = useState(marka);
    const url_marka = "--url here--" +varlik_turu;

    
    var marka_arr_new=[];
    const [marka_arr, setMarkaArr] = useState([]);

      axios.get(url_marka) 
      .then(res => {
        
        for(var i =0; i<res.data.items.length; i++){
          marka_arr_new.push(res.data.items[i].d);
        }
    
        setMarkaArr(marka_arr_new);

      })


      const [selectedValueModel, setSelectedValueModel] = useState(model);


     
      var model_arr_new=[];
      const [model_arr, setModelArr] = useState([]);

      const AfterMarkaChange = (itemValue) =>{
        setSelectedValueMarka(itemValue);
        ModelGetir;
      }

      const url_model = " --url here-- "+varlik_turu+"/"+selectedValueMarka; //selectedValueMarka came from first picker

      const ModelGetir = () => {
      
        axios.get(url_model) 
         .then(res => {
         
         for(var i =0; i<res.data.items.length; i++){
         model_arr_new.push(res.data.items[i].d);
        }

         setModelArr(model_arr_new);

        })
      
      }


    return (

      <View style={styles.container}>
        <View >
           <Text style={{fontWeight:'bold', padding:8}}>Etiket No        :  {etiket_no}</Text>
           <Text style={{fontWeight:'bold', padding:8}}>Marka             :</Text>
           <Text style={{fontWeight:'bold', padding:8}}>Model             :</Text>
           <Text style={{fontWeight:'bold', padding:8}}>Seri No           :</Text>
           <Text style={{fontWeight:'bold', padding:8}}>Bölge              :</Text>
        </View>
        <View>
          <Picker 
            selectedValue={selectedValueMarka}
            style={{ height: 50, width: 150 }}
            onValueChange={AfterMarkaChange}>

            { marka_arr.map((value,index) => {
                 return <Picker.Item label={value} value={value} key={index} />}) }   

          </Picker>   
          <Picker
            selectedValue={selectedValueModel}
            style={{ height: 50, width: 150 }}
            onValueChange={(itemValue, itemIndex) => setSelectedValueModel(itemValue)}>

            { model_arr.map((value,index) => {
                 return <Picker.Item label={value} value={value} key={index} />}) }   

          </Picker>   
  
  
        </View>
    </View>
    );
  }
export default VeriGuncelleme;
1
One thing: ModelGetir; should be ModelGetir();?Vlad L
I tried it as you say but still when it is first open second picker don't show any data. I gave default value for the first picker's selected value with useState and I can see default value of the first picker on screen but there is still no value for second picker. How can I fixed this issue?iozy

1 Answers

0
votes

One of the problems with your code is that setting state is async. So when you do

      const AfterMarkaChange = (itemValue) =>{
        setSelectedValueMarka(itemValue);
        ModelGetir();
      }

your selectedValueMarka is still the old value when ModelGetir() gets executed. The typical way to code this is to useEffect and watch selectedValueMarka for changes.

It should be something like this:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import {
  StyleSheet,
  Text,
  View,
} from 'react-native';

import { Picker } from '@react-native-picker/picker';

const VeriGuncelleme = ({ route }) => {
  const { responseData } = route.params;
  const { kullaniciBilgisi } = route.params;

  const { bolge } = responseData.items[0];
  const { etiket_no } = responseData.items[0];
  const marka = responseData.items[0].uretici;
  const { model } = responseData.items[0];
  const { serino } = responseData.items[0];
  const { ad_soyad } = responseData.items[0];
  const { varlik_turu } = responseData.items[0];

  const [marka_arr, setMarkaArr] = useState([]);
  const [selectedValueModel, setSelectedValueModel] = useState(model);
  const [selectedValueMarka, setSelectedValueMarka] = useState(marka);
  const [model_arr, setModelArr] = useState([]);

  useEffect(() => {
    const url_marka = `--url here--${varlik_turu}`;
    const marka_arr_new = [];
    axios.get(url_marka)
      .then((res) => {
        for (let i = 0; i < res.data.items.length; i++) {
          marka_arr_new.push(res.data.items[i].d);
        }
        setMarkaArr(marka_arr_new);
      });
  }, []);

  useEffect(() => {
    const url_model = ` --url here-- ${varlik_turu}/${selectedValueMarka}`; // selectedValueMarka came from first picker
    const model_arr_new = [];
    axios.get(url_model)
      .then((res) => {
        for (let i = 0; i < res.data.items.length; i++) {
          model_arr_new.push(res.data.items[i].d);
        }
        setModelArr(model_arr_new);
      });
  }, [selectedValueMarka]);

  return (
    <View style={styles.container}>
      <View>
        <Text style={{ fontWeight: 'bold', padding: 8 }}>
          Etiket No        :
          {etiket_no}
        </Text>
        <Text style={{ fontWeight: 'bold', padding: 8 }}>Marka             :</Text>
        <Text style={{ fontWeight: 'bold', padding: 8 }}>Model             :</Text>
        <Text style={{ fontWeight: 'bold', padding: 8 }}>Seri No           :</Text>
        <Text style={{ fontWeight: 'bold', padding: 8 }}>Bölge              :</Text>
      </View>
      <View>
        <Picker
          selectedValue={selectedValueMarka}
          style={{ height: 50, width: 150 }}
          onValueChange={(newValue) => setSelectedValueMarka(newValue)}
        >

          { marka_arr.map((value, index) => <Picker.Item label={value} value={value} key={index} />) }

        </Picker>
        <Picker
          selectedValue={selectedValueModel}
          style={{ height: 50, width: 150 }}
          onValueChange={(itemValue, itemIndex) => setSelectedValueModel(itemValue)}
        >

          { model_arr.map((value, index) => <Picker.Item label={value} value={value} key={index} />) }

        </Picker>

      </View>
    </View>
  );
};
export default VeriGuncelleme;