Javascript 在react hook中获取时没有正确的数据
下面的代码在初始加载时运行良好,但单击“获取数据”按钮后,现在可以正确获取数据。让我知道我做错了什么 代码-Javascript 在react hook中获取时没有正确的数据,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,下面的代码在初始加载时运行良好,但单击“获取数据”按钮后,现在可以正确获取数据。让我知道我做错了什么 代码- const Sample = () => { const [todoCount, setTodoCount] = useState(3); const [todos, setTodos] = useState([]); useEffect(() => { Array(todoCount) .fill() .map((_x, i) =
const Sample = () => {
const [todoCount, setTodoCount] = useState(3);
const [todos, setTodos] = useState([]);
useEffect(() => {
Array(todoCount)
.fill()
.map((_x, i) => {
return axios
.get(`https://jsonplaceholder.typicode.com/todos/${i + 1}`)
.then((res) => {
const todo = res.data.title;
setTodos((prevTodos) => {
return [...prevTodos, todo];
});
});
});
}, [todoCount]);
const fetchMore = (e) => {
setTodoCount((prevCount) => prevCount + 1);
};
return (
<div className="example">
<h3>Fetch data in a loop</h3>
<ul>
{todos.map((x, i) => (
<li key={i}>{x}</li>
))}
</ul>
<button onClick={fetchMore}>Fetch More</button>
</div>
);
};
export default Sample;
const Sample=()=>{
常量[todoCount,setTodoCount]=useState(3);
const[todos,setTodos]=useState([]);
useffect(()=>{
数组(todoCount)
.fill()
.map((x,i)=>{
返回轴
.得到(`https://jsonplaceholder.typicode.com/todos/${i+1}`)
。然后((res)=>{
const todo=res.data.title;
setTodos((prevTodos)=>{
返回[…上一个todo,todo];
});
});
});
},[todoCount]);
常量fetchMore=(e)=>{
setTodoCount((prevCount)=>prevCount+1);
};
返回(
在循环中获取数据
{todos.map((x,i)=>(
- {x}
))}
多拿些
);
};
导出默认样本;
代码沙盒-
预期结果-
您面临这种行为,因为一旦
todoCount
更新useffect
就会再次运行。现在todoCount
总共是4个,这样它将再获取4个todo(大多数将重复,因为只有最后一个i
值应该会带来一个新值)
根据您的代码,您可以在装载时中断初始计数获取,然后中断其他计数获取后续计数:
const initialCount = 3
const baseUrl = 'https://jsonplaceholder.typicode.com/todos'
const Sample = () => {
const [todoCount, setTodoCount] = useState(initialCount);
const [todos, setTodos] = useState([]);
useEffect(() => {
Array(initialCount)
.fill()
.map((_x, i) => {
return axios
.get(`${baseUrl}/${i + 1}`)
.then((res) => {
const todo = res.data.title;
setTodos((prevTodos) => {
return [...prevTodos, todo];
});
});
});
}, []);
useEffect(() => {
if (todoCount === initialCount) return
axios
.get(`${baseUrl}/${todoCount}`)
.then((res) => {
const todo = res.data.title;
setTodos((prevTodos) => {
return [...prevTodos, todo];
});
})
}, [todoCount])
虽然todoCount
是从todos
长度派生出来的,这是一种冗余状态,但您可以将其删除。之后,您可以只更改一个useffect
,并将fetch函数更改为使用todos.length
作为参考:
const initialCount = 3
const baseUrl = 'https://jsonplaceholder.typicode.com/todos'
const Sample = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
Array(initialCount)
.fill()
.map((_x, i) => {
return axios
.get(`${baseUrl}/${i + 1}`)
.then((res) => {
const todo = res.data.title;
setTodos((prevTodos) => {
return [...prevTodos, todo];
});
});
});
}, []);
const fetchMore = (e) => {
axios
.get(`${baseUrl}/${todos.length + 1}`)
.then((res) => {
const todo = res.data.title;
setTodos((prevTodos) => {
return [...prevTodos, todo];
});
});
};
如果在map函数中运行
setTodos
,则每次累积Todos
时都会运行。您可以尝试以下方法:
const Sample = () => {
const [todoCount, setTodoCount] = useState(3);
const [todos, setTodos] = useState([]);
useEffect(() => {
const todoArray = Array(todoCount)
.fill()
.map((_x, i) => {
return axios
.get(`https://jsonplaceholder.typicode.com/todos/${i + 1}`)
.then((res) => {
const todo = res.data.title;
return todo;
});
});
Promise.all(todoArray).then((todos) => {
console.log(todos);
setTodos(todos);
});
}, [todoCount]);
立即设置todo也会使应用程序在每次fetchMore点击时只重新呈现一次,而不是在结果中的每个todo。谢谢你的回答,但你不认为这会在代码中造成重复吗?是的,你是对的,我会将axios逻辑抽象到某个函数中,并封装到useCallback中。我没有这样做,因为这不是问题的重点。谢谢你的良好做法:)+1这也解决了你的问题,你得到了你的预期结果,不是吗?