标签: use-effect

useEffect 钩子没有被 jest.spyOn 嘲笑

我是 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)

javascript jestjs react-hooks use-effect

7
推荐指数
1
解决办法
7183
查看次数

UseEffect - 使用状态创建外部链接

我有一个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)

在此处输入图片说明

javascript reactjs react-hooks use-effect

7
推荐指数
1
解决办法
1331
查看次数

为什么 useEffect 不能在 return 语句中访问我的状态变量?

我不明白为什么我的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 …

reactjs next.js use-effect

7
推荐指数
2
解决办法
5780
查看次数

React Hooks useEffect,添加依赖项触发无限循环

在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)

javascript reactjs react-hooks use-effect

6
推荐指数
1
解决办法
1432
查看次数

检查 useEffect 中的哪个依赖项已更新

我有这个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)

reactjs use-effect

6
推荐指数
1
解决办法
4761
查看次数

useEffect 中可以有条件地进行不同的清理吗?

所以,我有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或我缺少某些内容时才进行?

reactjs react-hooks use-effect

6
推荐指数
1
解决办法
6414
查看次数

道具更改不触发 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)

reactjs react-props react-jsonschema-forms use-effect

6
推荐指数
1
解决办法
6555
查看次数

useEffect() 中缺少依赖项真的会导致数据过时吗?

我问这个问题是为了确认我对某些概念的理解。

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 如此推荐包含所有依赖项。人们通常使用依赖数组来绕过某些运行效果。如果他们省略了依赖项,这可能就是他们想要的。如果是失误,他们很容易注意到效果没有运行并采取行动。

javascript reactjs react-hooks use-effect

6
推荐指数
1
解决办法
239
查看次数

React 状态未在 useEffect() 上给出正确的值

我正在尝试使用 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)

javascript reactjs react-hooks use-effect use-state

6
推荐指数
1
解决办法
781
查看次数

什么时候应该使用 useEffect 挂钩而不是事件侦听器?

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听众吗?

event-listener reactjs react-hooks use-effect use-state

6
推荐指数
1
解决办法
2105
查看次数