使用 React Hooks 的依赖下拉菜单
Dependent Dropdown with React Hooks
我是 React 的新手,一直很难实现这个依赖下拉菜单。我想获取状态列表并过滤掉呈现到第二个下拉列表的位置。以下是我尝试实施的内容。状态和位置数据来自 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
试试这个
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([])
//i set api location in state
const [apiLocation, setAPILocation] = useState(`/api/merchant/locations/`)
// 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);
}
)
fetch(apiLocation)
.then(res => res.json())
.then((result) => {
setIsLoaded(true);
setLocations(result);
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
checkUrlLocation(url, newValue) {
let splited = url.split('/')
splited[splited.length - 1] = newValue
return splited.join('/')
}
return (
<div>
<form onChange={loadLocations}>
<label for="states">Choose a State:</label>
<select id="states" name="states" onChange={(e) =>{
/* in this case, if you select i states, it will put state id in api location and re-run useEffect */
setAPILocation(checkUrlLocation(apiLocation,e.target.value))
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 => (
<option key={location.id} value={location.id}>{location.name}</option>
))}
</select>
</form>
</div>
)
}
export default NullView
您可以将两次提取分成单独的 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>
);
我是 React 的新手,一直很难实现这个依赖下拉菜单。我想获取状态列表并过滤掉呈现到第二个下拉列表的位置。以下是我尝试实施的内容。状态和位置数据来自 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
试试这个
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([])
//i set api location in state
const [apiLocation, setAPILocation] = useState(`/api/merchant/locations/`)
// 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);
}
)
fetch(apiLocation)
.then(res => res.json())
.then((result) => {
setIsLoaded(true);
setLocations(result);
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
checkUrlLocation(url, newValue) {
let splited = url.split('/')
splited[splited.length - 1] = newValue
return splited.join('/')
}
return (
<div>
<form onChange={loadLocations}>
<label for="states">Choose a State:</label>
<select id="states" name="states" onChange={(e) =>{
/* in this case, if you select i states, it will put state id in api location and re-run useEffect */
setAPILocation(checkUrlLocation(apiLocation,e.target.value))
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 => (
<option key={location.id} value={location.id}>{location.name}</option>
))}
</select>
</form>
</div>
)
}
export default NullView
您可以将两次提取分成单独的 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>
);