我有两个 React 问题。
使用 useEffect 我正在调用一个 api:
React.useEffect(() => {
//API get call
},[]);
api 的结果存储在数组中。
问题 1:我知道 useEffect 是异步方法,但是有什么方法可以让我在 useEffect 返回后使用 useState 来初始化 dropdown 的值?
问题 2:如何使用数组的值初始化 forEach 循环内部的值?
答案 0 :(得分:1)
在 useEffect
中的 API 调用之后,调用您要保存到的 useState
的设置状态。例如:
const [state, setState] = useState([]);
const someFetch = async () => {
// using JS fetch API
const result = await fetch("getFetchSomeData");
// assuming the state is in the form of an array
setState(result.json())
}
useEffect(() => }{
someFetch();
});
return (
// rendering the array of fetched state this will update on next render after fetch
<div>{state}</div>
):
答案 1 :(得分:1)
问题 1
我可能会这样做:
function MyComponent() {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState(undefined);
useEffect(() => {
async function getData() {
setIsLoading(true);
const data = await /* API call */
setData((prevVal) => data);
setIsLoading(false);
}
getData();
}, []);
if (loading) return <h1>Loading...</h1>;
if (!loading && !data) return <h1>Error!</h1>;
return (
/* your component */
);
}
本质上,您必须解决钩子的“异步”方面。
问题 2
您没有说明要初始化什么,但我假设某种组件需要来自 API 的值。以下示例使用 HTML select
元素。使用 map()
。
<select>
{
data && data.map(({value, label}, index) => (
<option key={index} value={value}>{label}</option>
))
}
</select>
答案 2 :(得分:0)
问题 1:我知道 useEffect 是异步方法,但是有什么方法可以让我在 useEffect 返回后使用 useState 来初始化 dropdown 的值?
不,我们不能在 useEffect 运行后初始化 useState。 useEffect
钩子总是在第一次渲染之后和每次更新之后运行。我们还需要在第一次渲染时为状态提供初始化值。然后当 useEffect 运行时,我们可以简单地通过设置它来更新状态。
function App(){
const [stateVariable, setStateVariable] = useState(null);
useEffect(() => {
async function fetchApiCall(){
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => setStateVariable(data));
}
fetchApiCall(); // function call
},[]);
}
<块引用>
问题 2:如何使用数组的值初始化 forEach 循环中的值?
现在我们的 stateVariable 中有我们的数据。很可能来自 API 的数据位于对象数组 [JSON] 中。
Array.prototype.map()
函数在这里可能会有所帮助。根据 mdn docs,
map() 方法创建一个新数组,其中填充了对调用数组中的每个元素调用提供的函数的结果。
function processEachElement(element, index){
return <li key={index}>{element}</li>;
}
const newData = data.map(processEachElement);
// Now the newData is an array of `JSX.Elements`. Remember, not an array of objects.
所以,最终代码如下,
function App() {
const [stateVariable, setStateVariable] = useState(null);
useEffect(() => {
async function fetchApiCall() {
fetch("http://example.com/movies.json")
.then((response) => response.json())
.then((data) => setStateVariable(data));
}
fetchApiCall(); // function call
}, []);
function processEachElement(element, index) {
return <li key={index}>{element}</li>;
}
const newData = data.map(processEachElement);
return <ul>{newData}</ul>;
}