所以我得到了这个组件:
export default function () {
const [todos, setTodos] = useState([]);
useEffect(() => {
function populateTodos () {
axios.get(`http://localhost:8000/api/all-todos`)
.then(res => setTodos(res.data))
.catch(err => console.log(err));
}
populateTodos();
}, []);
console.log(todos);
return (
<div>
...
</div>
);
}
我正在使用useEffect
钩子从数据库中获取所有待办事项,并且工作正常。问题是,我每次修改todos数组(例如添加,删除或更新)时,都不知道如何使用useEffect
来触发重新渲染。如果我为useEffect
的依赖项数组提供todos
变量,则会在控制台中记录一个无限循环。
每当useEffect
数组更新时,如何使用todos
触发重新渲染?
答案 0 :(得分:1)
问题在于useEffect内部没有逻辑,请参见下面的代码
const [todos, setTodos] = useState([]);
useEffect(() => {
setTodos([1])
}, [todos])
这也将产生无限循环。但是我们总是给予相同的价值。问题是,当它更新时,依赖项为true,因此它再次开始执行useEffect()。您必须提出一些具体的逻辑,例如length
被更改,或者您可以采用一种新的状态,就像下面这样
const [todos, setTodos] = useState([]);
const [load, setLoad] = useState(false);
useEffect(() => {
function populateTodos () {
axios.get(`http://localhost:8000/api/all-todos`)
.then(res => setTodos(res.data))
.catch(err => console.log(err));
}
populateTodos();
}, [load])
console.log(todos)
return (
<div>
<button
onClick={() => {
todos.push(1)
setLoad(!load)
}}
>cilck</button>
</div>
);
答案 1 :(得分:0)
您可以通过获取父组件中的待办事项,然后将结果作为prop传递给依赖于它的useEffect的子组件,来提升状态。为了更新列表,必须在父组件中调用任何CRUD操作(但是您可以通过将这些函数传递给子组件来触发子组件的修改)。
否则,这对于Redux也是一个很好的应用程序。您将能够使用Redux fetch操作初始化组件,以对任何组件执行的所有CRUD操作填充存储,还可以通过修改reducer的API响应来更新存储。然后,您可以将商店用作useEffect依赖项,以更新组件的本地待办事项状态。
// State
const [todos, setTodos] = useState(null);
// Redux Stores
const todoStore = useSelector(state => state.todoStore);
// Redux Dispatch
const dispatch = useDispatch();
// Lifecycle: initialize the component's todolist
useEffect(() => {
if (!todos) {
// your Redux Action to call the API fetch & modify the store
dispatch(fetchTodos);
}
}, [dispatch, todos]
// Lifecycle: update the todolist based on changes in the store
// (in this case I assume the data is populated into todoStore.items)
useEffect(() => {
if (todoStore.items.length > 0) {
setTodos(todoStore);
}
}, [todoStore.items]
return {
<div>{ todos.map((todo, index) => <li key={'todo_'+index}>{todo}</li>) }</div>
}