我正在玩React钩子并面临一个问题.当我尝试使用事件监听器处理的按钮来控制日志时,它显示错误的状态.
CodeSandbox: https ://codesandbox.io/s/lrxw1wr97m
为什么它显示错误的状态?在第一张卡中,Button2应在控制台中显示2张卡.有任何想法吗?
import React, { useState, useContext, useRef, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const CardsContext = React.createContext();
const CardsProvider = props => {
const [cards, setCards] = useState([]);
const addCard = () => {
const id = cards.length;
setCards([...cards, { id: id, json: {} }]);
};
const handleCardClick = id => console.log(cards);
const handleButtonClick = id => console.log(cards);
return (
<CardsContext.Provider
value={{ cards, addCard, handleCardClick, handleButtonClick }}
>
{props.children} …Run Code Online (Sandbox Code Playgroud)我不明白为什么当我使用setTimeout函数时我的react组件启动到无限的console.log.一切正常,但PC开始落后于地狱.有些人说超时功能会改变我的状态和rerender组件,设置新的计时器等等.现在我需要了解如何清除它是正确的.
export default function Loading() {
// if data fetching is slow, after 1 sec i will show some loading animation
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
console.log('this message will render every second')
return 1
}
Run Code Online (Sandbox Code Playgroud)
清除不同版本的代码无助于:
const [showLoading, setShowLoading] = useState(true)
let timer1 = setTimeout(() => setShowLoading(true), 1000)
useEffect(
() => {
return () => {
clearTimeout(timer1)
}
},
[showLoading]
)
Run Code Online (Sandbox Code Playgroud) 代码在这里:https://codesandbox.io/s/nw4jym4n0
export default ({ name }: Props) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCounter(counter + 1);
}, 1000);
return () => {
clearInterval(interval);
};
});
return <h1>{counter}</h1>;
};
Run Code Online (Sandbox Code Playgroud)
问题是每次setCounter触发重新渲染,因此间隔重置并重新创建.这可能看起来很好,因为状态(计数器)保持递增,但是当与其他挂钩组合时它可能会冻结.
这样做的正确方法是什么?在类组件中,使用保持间隔的实例变量很简单.
我想这是因为JS的工作原理,但是我想的类不会遇到这个问题。在此代码中:
let [open, setOpen] = React.useState(false);
let [counter, setCounter] = React.useState(0);
function handleClick() {
setOpen(true);
setInterval(() => {
console.log(counter);
setCounter(counter + 1);
}, 2000);
}
Run Code Online (Sandbox Code Playgroud)
如果我一次调用handleClick (例如,单击按钮),则控制台上登录的值始终为0(尽管每次都会更新状态)。
这可能是由于关闭。但是,如果我想查看counter此类设置的最新值怎么办?使用类,您可以完成任务this.state.counter,并且它将读取最新值。挂钩是否有解决方法?
演示。
我发现这个问题基本相同。不知何故,我在最初的搜索中没有遇到它。
我在这方面遇到了很多麻烦,我尝试了各种方法。我想在单击开始按钮后每秒调用一个函数,然后在单击停止按钮后暂停它。我不断出现我无法解释的奇怪行为。我怎样才能在没有课程的情况下做出反应?
我有 triid 的东西:
const simulation = () => {
if (!running) {
console.log('hit');
return
} else {
// console.log(grid);
console.log('hey');
setTimeout(simulation, 1000)
}
}
Run Code Online (Sandbox Code Playgroud)
和
enter setInterval(() => {
let newGrid = [...grid]
for (let i = 0; i < numRow; i++) {
for (let k = 0; k < numCol; k++) {
let n = 0;
}
}
console.log(grid);
}, 5000)
Run Code Online (Sandbox Code Playgroud)
我已经尝试了更多,在某些情况下,它会更新状态,我应该添加到它,但在我重置状态后没有更新它。我如何调用一个函数来每隔一秒运行一次更新的状态值*请注意,我想要运行的函数将更新状态
除了在后台保留一个“时钟”以使用react钩子在轮播中实现自动下一个(几秒钟后)之外,还有其他选择吗?
下面的自定义react挂钩实现了轮播的状态,该轮播支持手动(下一步,上一步,重置)和自动(启动,停止)方法来更改轮播的当前(活动)索引。
const useCarousel = (items = []) => {
const [current, setCurrent] = useState(
items && items.length > 0 ? 0 : undefined
);
const [auto, setAuto] = useState(false);
const next = () => setCurrent((current + 1) % items.length);
const prev = () => setCurrent(current ? current - 1 : items.length - 1);
const reset = () => setCurrent(0);
const start = _ => setAuto(true);
const stop = _ => setAuto(false);
useEffect(() => {
const interval = setInterval(_ => …Run Code Online (Sandbox Code Playgroud) 大家早上好/下午好,
我已经使用 React 几个月了。我试图避免使用 React 组件,而是使用 React Hooks,但我不得不承认,有时我的目标会变得复杂。
其中一个时刻是在渲染组件后仅执行一次函数。typeText就我而言,我只想在渲染所有组件后执行一次递归函数 ( )。
下面是一个react项目的例子:
import React, { useEffect, useState } from "react";
export default function App() {
const [word, setWord] = useState("");
const list = ["Bag", "Door", "Shelving"];
let isWriting = true;
let selectedWord = 0,
position = 0,
delay = 0;
const typeText = () => {
if (isWriting === true) {
if (position < list[selectedWord].length) {
setWord(word + …Run Code Online (Sandbox Code Playgroud) useEffect我有一个下拉菜单,当更改时调用 api 使用钩子获取数据:
const [selectedComplianceFilter, setComplianceFilter] = useState("all");
useEffect(() => {
if (selectedComplianceFilter === "all") {
fetchFullReport();
} else {
fetchReportByCompliance(selectedComplianceFilter);
}
}, [selectedComplianceFilter]);
<select
name="compliance"
className="custom-select w-auto"
onChange={e => setComplianceFilter(e.target.value)}
>
<option value="all">All</option>
{compliances.map((compliance, i) => (
<option key={i} value={compliance}>
{compliance}
</option>
))}
</select>
Run Code Online (Sandbox Code Playgroud)
我有另一个useEffect钩子,它调用另一个返回扫描状态的 api
useEffect(() => {
fetchCompliances();
let intervalId;
getScanStatus(0);
fetchFullReport();
intervalId = setInterval(() => {
getScanStatus(intervalId);
}, 10000);
return () => {
componentDidUnmount.current = true;
clearInterval(intervalId);
};
}, []);
Run Code Online (Sandbox Code Playgroud)
这是获取扫描状态的函数:
const [scanStatus, …Run Code Online (Sandbox Code Playgroud) 如果我使用 setInterval(line 15) 而不使用 useEffect ,那么它给出的结果是 2^n-1(0,1,3,7,15,31,63...) 而不是(0,1,2,3,4, ..)。所以我有一些问题
1)为什么当我直接调用setInterval而不使用useEffect时我会得到该输出2)如果我更改setCount(第9行)并且它通过直接使用setInterval而不使用useEffect给出正确的输出(就像我所做的那样)有什么办法3)如果没有useEffcet就不可能使用setInterval,那么为什么不可能呢?
如果我将 setInterval 放入 useEffect 中并最初渲染一次(第 12,13,14 行),那么它会给出正确的输出......但是当我直接使用 setInterval 时,我没有得到正确的输出。什么是差异赌注?
在这两种情况下,我都调用 setInterval 一次,但输出是 diff。
import React, {useEffect, useState } from 'react'
export default function IncorrectDependency() {
const [count,setCount]=useState(0)
const inc=()=>{
// console.log(count)
setCount(preVal=>preVal+1)
// setCount(count+1)
}
// useEffect(()=>{
// setInterval(inc,1000)},[]
// )
setInterval(inc,1000)
return (
<div>
<h1>{count}</h1>
</div>
)
}
Run Code Online (Sandbox Code Playgroud) reactjs ×9
javascript ×8
react-hooks ×6
setinterval ×2
async-await ×1
carousel ×1
react-redux ×1
settimeout ×1