Search code examples
reactjsreact-hooksdrop-down-menu

Options of next dropdown should based one previous one


I have a database

[
    {
        "ID": 3,
        "fourth_ip": "5",
        "location": "jp",
        "third_ip": "20"
    },
    {
        "ID": 4,
        "fourth_ip": "123",
        "location": "jp",
        "third_ip": "21"
    },
    {
        "ID": 5,
        "fourth_ip": "123",
        "location": "hk",
        "third_ip": "20"
    },
    {
        "ID": 6,
        "fourth_ip": "200",
        "location": "sg",
        "third_ip": "11"
    },
    {
        "ID": 7,
        "fourth_ip": "6",
        "location": "jp",
        "third_ip": "20"
    },
    {
        "ID": 8,
        "fourth_ip": "200",
        "location": "sg",
        "third_ip": "12"
    }
]

how can i create 3 select with location, third_ip and fourth_ip, they must be related to each other. like if localtion is jp, third_ip select should be 20,21 and when selected 20 fourth_ip should be 5,6. Another problem is when I open the page first time, it will be the correct. Location is jp, third_ip is 20 and fourth_ip is 5. But when I select location to hk, third_ip is 20 , but fourth_ip is null.

useEffect(() => {
        // setEdgeData(data)
        const edgeLocation:never[] = Array.from(new Set(data.map((item: { location: any; }) => item.location)));

        setEdgeLocation(edgeLocation);
        // setRegion(edgeLocation[0])
        if (!region) {
            setRegion(edgeLocation[0]);
        }
        console.log(region)


    }, [data]);

    useEffect(() => {
        setThirdIP("")
        const selectedThirdIP:never[] = Array.from(new Set(
            data
                .filter((item: { location: string; }) => item.location === region)
                .map((item: { third_ip: any; }) =>  item.third_ip)));
        console.log(selectedThirdIP)
        console.log(selectedThirdIP[0])
        setSelectedThirdIP(selectedThirdIP)
        if (!thirdIP) {
            setThirdIP(selectedThirdIP[0])
        }
        console.log('thirdip = '+thirdIP)
    }, [region]);
    console.log('thirdip = '+thirdIP)

    useEffect(() => {
        const selectedFourthIP:never[] = Array.from(new Set(
            data
                .filter((item: { location: string, third_ip: string }) => item.location === region && item.third_ip === thirdIP)
                .map((item: { fourth_ip: any; }) =>  item.fourth_ip)));
        console.log(selectedFourthIP)
        console.log(selectedFourthIP[0])
        setSelectedFourthIP(selectedFourthIP)
        if (!fourthIP) {
            setFourthIP(selectedFourthIP[0])
        }
        console.log(fourthIP)

    }, [region, thirdIP]);
    console.log(fourthIP)




        <select onChange={handleRegionChange} value={region}>
            {edgeLocation.map((location) => (
                <option key={location} value={location}>
                    {location}
                </option>
            ))}
        </select>
        </p>


        <select onChange={handleThirdIPChange} value={thirdIP}>
        {selectedThirdIP.map((thirdIP) => (
            <option key={thirdIP} value={thirdIP}>
                {thirdIP}
            </option>
        ))}
        </select>.
        <select onChange={handleFourthIPChange} value={fourthIP}>
        {selectedFourthIP.map((fourthIP) => (
            <option key={fourthIP} value={fourthIP}>
                {fourthIP}
            </option>
        ))}
    </select>

At fist third_ip and fourth_ip didn't write in useEffect, but that lead to first time open the page ,if I don't selected the localtion third_ip and fourth_ip will be null


Solution

  • I just only thought about this

    how can i create 3 select with location, third_ip and fourth_ip, they must be related to each other. like if localtion is jp, third_ip select should be 20,21 and when selected 20 fourth_ip should be 5,6.

    try this.

    export default function App({
      data = [],
    }: {
      data: { ID: number; fourth_ip: string; location: string; third_ip: string }[];
    }) {
      const [locations, setLocations] = useState([]);
      const [thirdIPs, setThirdIPs] = useState([]);
      const [fourthIPs, setFourthIPs] = useState([]);
      const [selectedLocation, setSelectedLocation] = useState('');
      const [selectedThirdIP, setSelectedThirdIP] = useState('');
      const [selectedFourthIP, setSelectedFourthIP] = useState('');
    
      const handleLocationChange = (e) => {
        setSelectedLocation(e.target.value);
        makeThirdIPs(e.target.value);
      };
      const handleThirdIPChange = (e) => {
        setSelectedThirdIP(e.target.value);
        makeFourthIPs(selectedLocation, e.target.value);
      };
      const handleFourthIPChange = (e) => {
        setSelectedFourthIP(e.target.value);
      };
    
      const makeThirdIPs = (region: string) => {
        const ips = Array.from(
          new Set(
            data
              .filter(({ location }) => location === region)
              .map(({ third_ip }) => third_ip)
          )
        );
        setThirdIPs(ips);
        setSelectedThirdIP(ips[0]);
        makeFourthIPs(region, ips[0]);
      };
    
      const makeFourthIPs = (region: string, thirdIP: string) => {
        const ips = Array.from(
          new Set(
            data
              .filter(
                ({ location, third_ip }) =>
                  location === region && third_ip === thirdIP
              )
              .map(({ fourth_ip }) => fourth_ip)
          )
        );
        setFourthIPs(ips);
        setSelectedFourthIP(ips[0]);
      };
    
      useEffect(() => {
        const edgeLocation = Array.from(
          new Set(data.map(({ location }) => location))
        );
    
        setLocations(edgeLocation);
        setSelectedLocation(edgeLocation[0]);
        makeThirdIPs(edgeLocation[0]);
      }, [data]);
    
      return (
        <div>
          <select onChange={handleLocationChange} value={selectedLocation}>
            {locations.map((location) => (
              <option key={location} value={location}>
                {location}
              </option>
            ))}
          </select>
    
          <select onChange={handleThirdIPChange} value={selectedThirdIP}>
            {thirdIPs.map((thirdIP) => (
              <option key={thirdIP} value={thirdIP}>
                {thirdIP}
              </option>
            ))}
          </select>
    
          <select onChange={handleFourthIPChange} value={selectedFourthIP}>
            {fourthIPs.map((fourthIP) => (
              <option key={fourthIP} value={fourthIP}>
                {fourthIP}
              </option>
            ))}
          </select>
        </div>
      );
    }
    

    https://stackblitz.com/edit/react-ts-arjnsj?file=index.tsx