我是 React Hooks 的新手,我想要实现的是测试一个 React 组件(称为 CardFooter),该组件包含对 useEffect 钩子的调用,该钩子被触发并修改了全局上下文变量。
CardFooter.js:
const CardFooter = props => {
const [localState, setLocalState] = useState({
attachmentError: false
});
const globalContext = useContext(GlobalContext);
React.useEffect(()=> {
setLocalState({
...localState,
attachmentError: globalContext.data.attachmentError
});
},[globalContext.data.attachmentError]);
}
Run Code Online (Sandbox Code Playgroud)
CardFooter.test.js:
import Enzyme, { shallow } from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('<CardFooter />', () => {
let useEffect;
const mockUseEffect = () => {
useEffect.mockImplementation(f => f());
};
useEffect = jest.spyOn(React, "useEffect");
mockUseEffect(); //
it('should render correctly with no props.', () …Run Code Online (Sandbox Code Playgroud) 我有一个getUrl()调用 API 端点的方法
useEffect(() => {
getUrl()
.then(x => x.json())
.then(x => {
const { result } = x;
});
});
Run Code Online (Sandbox Code Playgroud)
我可以在控制台中看到我页面中的调用,正如您在屏幕截图中看到的,这是我的数据
{
"result":"https://www.google.it",
"error":null,
"errorCode":null,
"isSuccessful":true,
"operationStatusCode":"OK"
}
Run Code Online (Sandbox Code Playgroud)
如何在我的视图中在外部链接中显示以下result链接示例https://www.gooole.it?
我必须使用状态吗?
我需要一个如何编码的例子在这里
<a target="_blank" href={result}>Google Link</a>
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我的useEffect()React 函数无法访问我的组件的状态变量。当用户放弃在我们的应用程序中创建列表并导航到另一个页面时,我试图创建一个日志。我正在使用useEffect() return复制componentWillUnmount()生命周期方法的方法。你能帮我吗?
let[progress, setProgress] = React.useState(0)
... user starts building their listing, causing progress to increment ...
console.log(`progress outside useEffect: ${progress}`)
useEffect(() => {
return () => logAbandonListing()
}, [])
const logAbandonListing = () => {
console.log(`progress inside: ${progress}`)
if (progress > 0) {
addToLog(userId)
}
}
Run Code Online (Sandbox Code Playgroud)
代码将达到addToLog(),导致记录此行为。
这就是当用户在他们的列表中输入一些内容,导致progress增加,然后离开页面时发生的情况。
useEffect()方法完美运行,并触发该logAbandonListing()功能console.log()(上面useEffect)记录了大于 0 的progress状态console.log()用于日志0 …在useEffect内部,我有一个props依赖项(setIsValid)。当我将此依赖项添加到useEffect时,它会陷入无限循环。
调用子组件时为父:
const setIsValid = (bool) => {
const tmpStateCopy = Object.assign({}, state);
tmpStateCopy.isValid = bool;
setState(tmpStateCopy);
};
return <Child
setIsValid={setIsValid}
/>
Run Code Online (Sandbox Code Playgroud)
在子组件中:
const { setIsValid } = props;
const [state, setState] = useState({
transformations: [],
duplicateIndexes: []
});
const { transformations, duplicateIndexes } = state;
useEffect(() => {
const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
const hasDuplicates = duplicateIndexes.length > 0;
const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);
setIsValid(isValid) …Run Code Online (Sandbox Code Playgroud) 我有这个useEffect钩子:
useEffect(() => {
setTop(t => t + (controller.position.y * tileSize))
setLeft(l => l + (controller.position.x * tileSize))
}, [controller.position])
Run Code Online (Sandbox Code Playgroud)
我希望它只在发生position变化时才进行添加。如果发生tileSize变化,我只想让它进行乘法。
我尝试将其分成两部分useEffect,但随后收到React Hook useEffect has missing dependencies警告:
useEffect(() => {
setTop(t => t + (controller.position.y * spriteSize))
setLeft(l => l + (controller.position.x * spriteSize))
}, [controller.position])
useEffect(() => {
setTop((controller.position.y * spriteSize))
setLeft((controller.position.x * spriteSize))
}, [spriteSize])
Run Code Online (Sandbox Code Playgroud)
在这种情况下,最佳做法是什么?
编辑:
一个可重现的例子:
const [tileSize, setTileSize] = useState(0)
const controller = {
position: …Run Code Online (Sandbox Code Playgroud) 所以,我有useEffect这样的:
useEffect(()=>{
if(foo) {
// do something
return () => { // cleanup function }
}
}, [foo])
Run Code Online (Sandbox Code Playgroud)
在这里,cleanup即使if块被执行,该函数也永远不会被调用。但如果我修改一下效果为:
useEffect(()=>{
if(foo) {
// do something
}
return () => { // cleanup function }
}, [foo])
Run Code Online (Sandbox Code Playgroud)
有用。那么,清理工作是否仅return在最后一条语句useEffect或我缺少某些内容时才进行?
我有一个带有 useEffect 的 React 组件,当 props 更改时,该组件不会被触发。我希望这个组件根据 prop 更新它所显示的内容。然而,当 prop 改变时,什么也没有发生。
为了调试,我添加了一个可以手动更新值的按钮,效果很好。我只是无法让 useEffect 终生运行。
const ReadOnly = (props: WidgetProps) => {
const [value, setValue] = React.useState('No Value');
const { formContext } = props;
const firstName = () => formContext.queryData[0]?.basicInformation?.firstName ?? 'No value';
// This only runs once when the component is first rendered never fired when formContext updates.
React.useEffect(() => {
setValue(firstName());
}, [formContext]);
// This correctly updates the value
const onClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
setValue(firstName()); …Run Code Online (Sandbox Code Playgroud) 我问这个问题是为了确认我对某些概念的理解。
React 文档强调包含 useEffect() 回调中使用的所有依赖项。正如文档中所解释的:
我有点明白这个解释是从哪里来的。但我关心的是“陈旧价值”部分。我没有看到由于缺少依赖项而导致过时值发生任何可能的方式。我的论点也得到了文档中内容的支持:
经验丰富的 JavaScript 开发人员可能会注意到,传递给 useEffect 的函数在每次渲染时都会有所不同。这是故意的。事实上,这让我们可以从效果内部读取计数值,而不必担心它会过时。
据我的理解,如果我们错过列出依赖项,则该效果将不会在该依赖项更改引起的渲染后运行,因为 React 认为效果不依赖于它。如果我猜测,可能是文档提到引用过时数据时的情况。事实上,效果代码中的数据已经过时。但是,效果回调一开始并不运行。在效果运行之前我不会注意到数据已过时。如果这很重要,我将首先找出效果未运行的原因并解决问题。我感到困惑的不是数据过时,而是效果无法运行。
此外,我们假设效果在由另一个依赖项更改引起的渲染之后运行。在这种情况下,即使我们错过了依赖项,由于上述关闭原因,我们也不会读取过时的数据。我做了一些实验来证实这一点:
export default function App() {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(10);
useEffect(() => {
console.log(count2);
}, [count1]);
return (
<div className="App">
<div>
Count1: {count1}
<button onClick={() => setCount1(count1 + 1)}>increase</button>
</div>
<div>
Count2: {count2}
<button onClick={() => setCount2(count2 + 1)}>increase</button>
</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
只要效果运行,我们总是会得到最新的 count2。那么我的理解成立吗?
我想知道为什么 React 如此推荐包含所有依赖项。人们通常使用依赖数组来绕过某些运行效果。如果他们省略了依赖项,这可能就是他们想要的。如果是失误,他们很容易注意到效果没有运行并采取行动。
我正在尝试使用 React 构建因式分解算法。我想根据因式分解的结果进行results添加LocalStorage。但是,LocalStorage设置的是以前的结果而不是当前的结果。
我认为发生这种情况是因为useEffect在每个新的(=用户输入)上运行[number]而不是基于[results]. 但是,我需要useEffect在新的用户输入提交上运行,因为那时必须触发分解。
localStorage因式分解完成后(finally如果可能的话,在块上)如何才能得到正确的结果?
const [results, setResults] = useState({
default: [],
detailed: [],
isPrime: '',
});
const { number } = props
useEffect(() => {
handleWorker(number);
//accessing results here will give previous results
}, [number]);
const handleWorker = number => {
try {
const worker = new Worker(new URL('facto.js', import.meta.url));
worker.postMessage({ number, algorithm });
worker.onmessage = ({ data: { facto …Run Code Online (Sandbox Code Playgroud) useEffect当可以使用事件侦听器简化钩子时,是否应该使用钩子?
例如,在下面的代码片段中,我使用事件侦听器来更改某些状态,然后useEffect使用钩子对该状态更改做出反应并执行其他操作
import { useEffect, useState } from "react";
export default function Foo() {
const [isActive, setIsActive] = useState(true);
useEffect(() => {
// do any kind of business logic
}, [isActive]);
return (
<>
<button
type="button"
className="secondary"
onClick={() => setIsActive(true)}
>
ACTIVATE
</button>
<button
type="button"
className="secondary"
onClick={() => setIsActive(false)}
>
DEACTIVATE
</button>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
我应该将useEffect逻辑转移给onClick听众吗?
use-effect ×10
reactjs ×9
react-hooks ×7
javascript ×5
use-state ×2
jestjs ×1
next.js ×1
react-props ×1