![](/img/trans.png)
[英]how to rerender a page using UseEffect hook on window.innerWidth in react
[英]How can I make useEffect react hook rerender based on a variable value?
所以我得到了这个组件:
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
钩子从数据库中获取所有useEffect
,并且工作正常。 问题是我不知道如何使用useEffect
在我对 todos 数组进行修改时触发重新渲染,例如添加或删除或更新。 如果我使用todos
变量提供useEffect
的依赖数组,我会在控制台中得到一个无限循环日志。 如何在todos
数组更新时使用useEffect
触发重新渲染?
问题是 useEffect 内部没有逻辑,请参阅下面的代码
const [todos, setTodos] = useState([]);
useEffect(() => {
setTodos([1])
}, [todos])
这也会产生无限循环。 但我们总是给予相同的价值。 问题是当它被更新时,依赖是真的,所以它再次开始执行 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>
);
您可以通过在父组件中获取 todos来提升状态,然后将结果作为 prop 传递给 useEffect 依赖于它的子组件。 任何 CRUD 操作都必须在父组件中调用才能更新列表(但您可以通过将这些函数传递给子组件来触发子组件的修改)。
否则,这也将是 Redux 的一个很好的应用程序。 您将能够使用 Redux fetch 操作初始化组件,以使用在任何组件上完成的所有 CRUD 操作填充存储,并通过修改减速器的 API 响应更新存储。 然后你可以使用 store 作为 useEffect 依赖来更新组件的本地 todo 状态。
// 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>
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.