首页 > 解决方案 > 使用 React Hooks 的依赖下拉列表

问题描述

我是新来的反应,并且一直很难实现这个相关的下拉菜单。我想获取状态列表并过滤掉呈现到第二个下拉列表的位置。以下是我尝试实施的内容。状态和位置数据是从 API 中提取的。

我能够提取状态数据,但在实施依赖下拉列表时遇到了困难。任何帮助将不胜感激。

import React, { useState, useEffect } from 'react'

function NullView() {

    // //API CALL
    const [error, setError] = useState(null);
    const [isLoaded, setIsLoaded] = useState(false);
    const [items, setItems] = useState([]);

    const [state, setState] = useState(null);
    const [locations, setLocations] = useState([])
    // console.log(count)
    let loadLocations = (e) => {
        e.preventDefault();

    }

    useEffect(() => {
        fetch("/api/merchant/all/states/")
            .then(res => res.json())
            .then((result) => {
                setIsLoaded(true);
                setItems(result);
            },
                (error) => {
                    setIsLoaded(true);
                    setError(error);
                }
            )
        if (state != null) {
            fetch("/api/merchant/locations/2/")
                .then(res => res.json())
                .then((result) => {
                    setIsLoaded(true);
                    setLocations(result);
                },
                    (error) => {
                        setIsLoaded(true);
                        setError(error);
                    }
                )
        }


    }, [])


    return (
        <div>
            <form onChange={loadLocations}>
                <label for="states">Choose a State:</label>
                <select id="states" name="states" onChange={(e) => setState(e.target.value)}>
                    <option value="">Select State</option>

                    {items.map(states => (

                        <option key={states.id} value={states.id}>{states.name}</option>
                    ))}

                </select>


                <label for="location">Choose a Location:</label>
                <select id="location" name="location" onChange={(e) => setLocation(e.target.value)}>
                    <option value="">Select Location</option>

                    {Location.map(location => (

                        <option key={location.id} value={location.id}>{location.name}</option>
                    ))}

                </select>

            </form>

        </div>
    )
}

export default NullView

标签: javascriptreactjsdropdown

解决方案


您可以将两个提取分成单独的useEffect回调。第一个useEffect回调获取组件挂载并更新“状态”选项,而第二个回调useEffect依赖于当前选择的“状态”值。

useEffect(() => {
  fetch("/api/merchant/all/states/")
    .then((res) => res.json())
    .then((result) => setItems(result))
    .catch((error) => setError(error))
    .finally(() => setIsLoaded(true));
}, []); // <-- fetch once when component mounts

useEffect(() => {
  if (state) {
    fetch(`/api/merchant/locations/${state}`) // <-- compute request URL
      .then((res) => res.json())
      .then((result) => setLocations(result))
      .catch((error) => setError(error))
      .finally(() => setIsLoaded(true));
  }
}, [state]); // <-- fetch when state updates

我相信您的渲染中也有错字,Location应该是locations状态。

return (
  <div>
    <form onChange={loadLocations}>
      <label for="states">Choose a State:</label>
      <select
        id="states"
        name="states"
        onChange={(e) => setState(e.target.value)}
      >
        <option value="">Select State</option>
        {items.map((states) => (
          <option key={states.id} value={states.id}>
            {states.name}
          </option>
        ))}
      </select>

      <label for="location">Choose a Location:</label>
      <select
        id="location"
        name="location"
        onChange={(e) => setLocation(e.target.value)}
      >
        <option value="">Select Location</option>
        {locations.map((location) => ( // <-- render locations state
          <option key={location.id} value={location.id}>
            {location.name}
          </option>
        ))}
      </select>
    </form>
  </div>
);

推荐阅读