标签: react-strictmode

React 18 严格模式导致组件渲染两次

React 版本 18中对严格模式的更改导致我的代码渲染两次,这会导致axios abort 控制器出现错误,但我不知道如何在应用程序渲染两次后从浏览器控制台清除错误。

请注意:我正在开发一个注册/登录应用程序,即使在我成功登录后,由于axios错误, React也会将我带回登录页面

useEffect(() => {
    let isMounted = true;
    // used by axios to cancel request
    const controller = new AbortController();

    const getGoals = async () => {
        try {
            const response = await goalPrivate.get("/goals", {
                // option to cancel request
                signal: controller.signal
            })
            console.log(response?.data);
            // set goals state when component mounts
            isMounted && setGoals(response?.data);
        } catch (error) {
            console.log(error.message);
            // when refreshToken expires
            navigate("/login", { state: { from: …
Run Code Online (Sandbox Code Playgroud)

javascript development-environment reactjs react-strictmode

23
推荐指数
3
解决办法
3万
查看次数

如何在 React 18 中禁用严格模式?

简而言之,如何在 React 18 中禁用严格模式?我正在使用 React 18 和 create-react-app。

javascript reactjs create-react-app react-strictmode

17
推荐指数
2
解决办法
4万
查看次数

有没有办法检查 React 的“StrictMode”是否打开?

React 中有没有一种方法——无论是通过代码还是通过 React 开发工具——来查看组件是否正在ReactStrictMode中渲染?在我的梦想世界中,我可以有某种常数console.log,比如布尔值React.isStrictModeOnForThisComponentRendering;或者,当您在 React 开发工具中检查某个组件时,它会在侧面板的某个位置显示它是否在 StrictMode 下渲染。

明确地说,这个问题是:

  • 不是关于如何启用 StrictMode。(答案是<React.StrictMode>,尽管它也可以通过某些框架中的配置来设置,例如Next.js
  • 具体讨论 React 的严格模式StrictMode而不是 JavaScript 的( 'use strict';) 或TypeScript 的严格模式。这是一个重载的短语,但是 watcha 会怎样呢?
  • 由于使用 React 的 StrictMode 进行意外的双重渲染,您会感到困惑。请参阅此 GitHub 问题此 StackOverflow 帖子,了解它可能导致的挫败感。即使您无法判断组件树中的何处启用了 StrictMode,如果有一种简单的方法来验证组件是否在 StrictMode 下运行,那就太好了。

javascript reactjs react-strictmode

12
推荐指数
1
解决办法
5422
查看次数

严格模式与 React 18 的工作方式是否不同?

考虑下面的片段。在 React 18 中,count每次渲染都会在控制台上打印两次,但在 React 17 中只打印一次。

反应 18 示例:

function App() {
  const [count, setCount] = React.useState(0);
  console.log(count);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

反应 17 示例

function App() {
  const [count, setCount] = React.useState(0);
  console.log(count);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-strictmode

11
推荐指数
1
解决办法
9054
查看次数

在渲染期间而不是在 useEffect 中更改引用的值是否安全?

我用来useRef保存 prop 的最新值,以便稍后可以在异步调用的回调(例如 onClick 处理程序)中访问它。我使用 ref 而不是放入valueuseCallback 依赖项列表,因为我预计该值会频繁更改(当使用新的组件重新渲染时value),但 onClick 处理程序很少被调用,因此它是不值得在每次值更改时为元素分配新的事件侦听器。

\n
function MyComponent({ value }) {\n  const valueRef = useRef(value);\n  valueRef.current = value;  // is this ok?\n\n  const onClick = useCallback(() => {\n    console.log("the latest value is", valueRef.current);\n  }, []);\n\n  ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

React Strict Mode的文档让我相信执行副作用通常render()是不安全的。

\n
\n

由于上述方法[包括类组件render()和函数组件体]可能会被多次调用,因此\xe2\x80\x99重要的是它们不包含副作用。忽略此规则可能会导致各种问题,包括内存泄漏和无效的应用程序状态。

\n
\n

事实上,当我使用引用访问旧值时,我在严格模式下遇到了问题。

\n

我的问题是:是否担心从渲染函数分配的“副作用” ?valueRef.current = value例如,是否存在回调会收到过时值(或来自尚未提交的“未来”渲染的值)的情况?

\n

我能想到的一种替代方案是useEffect确保在组件渲染后更新引用,但从表面上看,这看起来没有必要。

\n …

reactjs react-hooks react-strictmode

10
推荐指数
1
解决办法
2371
查看次数

我应该在我的测试套件中使用 React.StrictMode 吗?

第一次发帖提问:)

我有一个React应用程序:

// index.js

ReactDOM.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>,
  document.getElementById('root'),
);
Run Code Online (Sandbox Code Playgroud)

我有 24 个jest测试套件,到目前为止,基本上是这样的:

act(() => {
  render(
    <Router>
      <SomeComponentIWantToTest />
    </Router>
  );
});
Run Code Online (Sandbox Code Playgroud)

我想到将测试包装在 中更合适StrictMode,以更接近应用程序的实际渲染方式:

act(() => {
  render(
    <React.StrictMode>
      <Router>
        <SomeComponentIWantToTest />
      </Router>
    </React.StrictMode>
  );
});
Run Code Online (Sandbox Code Playgroud)

尝试之后,我注意到以下几点:

  1. 一件好事是,它在我没有将一些测试代码包装在act. 我能够修复这些地方。欢呼!
  2. 我的测试速度显着减慢。我猜这是因为我的 React 组件由于 Strict Mode 而渲染了两次

另外,快速浏览一下文档这似乎StrictMode只是开发的事情。那么,将测试(理论上与生产中将发生的情况有关)包装起来有意义吗React.StrictMode

javascript unit-testing reactjs jestjs react-strictmode

8
推荐指数
1
解决办法
1692
查看次数

我可以在我的应用程序中保留 &lt;StrictMode&gt; 但使其不渲染两次吗

我的应用程序处于严格模式下,这使得使用 useEffect() 运行变得困难。它基本上在控制台中记录了我所有的值两次,这不是我想要实现的结果。

 useEffect(() => {
console.log('logs some data')
}, []);
Run Code Online (Sandbox Code Playgroud)

有没有办法让 useEffect 只显示一次数据并将 StrictMode 保留在我的应用程序组件中?

root.render(
<React.StrictMode>
 <App />
</React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)

我确实尝试使用 useRef 方法,但我的工作人员建议我不要使用此特定方法并尝试其他可能的outwork。


解决方案:如果您需要在组件中保留严格模式,但需要使 useEffect 不渲染两次,您可以使用 useRef :

例子:

 let shouldlog = useRef(true);

 useEffect(() => {
 if (shouldlog.current) {
  shouldlog.current = false;
  console.log("component mounted");
  }

return () => console.log("function cleaned up");
}, []);
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-hooks react-strictmode

8
推荐指数
1
解决办法
5038
查看次数

我应该在生产中手动禁用 React StrictMode 吗?

我正在阅读文档并了解到 React仅StrictMode用于开发,它解释了为什么我们有双重调用。

这很好,但这是否意味着我必须StrictMode为我的生产禁用手动功能,或者反应build命令是否会自行执行此操作?

reactjs react-strictmode

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

React 18 StrictMode第一次useEffect错误状态

另一个 React 18 严格模式问题。我知道 React 将调用渲染和效果函数两次,以突出即将推出的功能中潜在的内存泄漏。我还不明白的是如何正确处理这个问题。我的问题是,我无法正确卸载第一个渲染结果,因为两个 useEffect 调用是使用第二个渲染的状态执行的。这是一个例子来展示我的意思。


  const ref = useRef(9);
  const id = useId();

  console.log('@@ initial id', id);
  console.log('@@ initial ref', ref.current);

  ref.current = Math.random();

  console.log('@@ random ref', ref.current);

  useEffect(() => {
    console.log('@@ effect id', id);
    console.log('@@ effect ref', ref.current);

    return () => {
      console.log('@@ unmount id', id);
      console.log('@@ unmount ref', ref.current);
    };
  });
Run Code Online (Sandbox Code Playgroud)

这是日志输出

@@ initial id :r0:
@@ initial ref 9
@@ random ref 0.26890444169781214
@@ initial id :r1:
@@ initial ref 9
@@ random ref …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-strictmode

5
推荐指数
1
解决办法
1073
查看次数

反应严格模式

我正在处理我的项目,我注意到当打开严格模式时,它会将两个相同的元素推入我的数组中。当严格模式关闭时,它仅将一个元素推入数组。有什么解释为什么会发生这种情况吗?

import {getRandomNumber} from './utils';


export function registerTicket() {
    const newTicket = {
        number: getRandomNumber(),
        color: 'red',
    }
    this.setState((prevState) => {
        prevState.tickets.push(newTicket);
        return {
            remainingTickets: --prevState.remainingTickets,
            tickets: prevState.tickets,

        }
    })
}
Run Code Online (Sandbox Code Playgroud)

这是我的状态。

    this.state = {
      winningNumber: getRandomNumber(),
      remainingTickets: 5,
      tickets: [],
      finished: false
    };
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-strictmode

2
推荐指数
1
解决办法
500
查看次数