diff --git a/reflex/.templates/jinja/web/pages/_app.js.jinja2 b/reflex/.templates/jinja/web/pages/_app.js.jinja2
index 40e31dee6..ee3e24540 100644
--- a/reflex/.templates/jinja/web/pages/_app.js.jinja2
+++ b/reflex/.templates/jinja/web/pages/_app.js.jinja2
@@ -38,13 +38,13 @@ export default function MyApp({ Component, pageProps }) {
}, []);
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js
index 93c664ef1..1eeb4e64a 100644
--- a/reflex/.templates/web/utils/state.js
+++ b/reflex/.templates/web/utils/state.js
@@ -301,10 +301,7 @@ export const applyEvent = async (event, socket) => {
// Send the event to the server.
if (socket) {
- socket.emit(
- "event",
- event,
- );
+ socket.emit("event", event);
return true;
}
@@ -497,7 +494,7 @@ export const uploadFiles = async (
return false;
}
- const upload_ref_name = `__upload_controllers_${upload_id}`
+ const upload_ref_name = `__upload_controllers_${upload_id}`;
if (refs[upload_ref_name]) {
console.log("Upload already in progress for ", upload_id);
@@ -833,6 +830,13 @@ export const useEventLoop = (
}
})();
}
+
+ // Cleanup function.
+ return () => {
+ if (socket.current) {
+ socket.current.disconnect();
+ }
+ };
});
// localStorage event handling
diff --git a/reflex/app.py b/reflex/app.py
index 9fe0f2992..3ba1ff53f 100644
--- a/reflex/app.py
+++ b/reflex/app.py
@@ -54,6 +54,7 @@ from reflex.compiler.compiler import ExecutorSafeFunctions, compile_theme
from reflex.components.base.app_wrap import AppWrap
from reflex.components.base.error_boundary import ErrorBoundary
from reflex.components.base.fragment import Fragment
+from reflex.components.base.strict_mode import StrictMode
from reflex.components.component import (
Component,
ComponentStyle,
@@ -943,6 +944,12 @@ class App(MiddlewareMixin, LifespanMixin):
# If a theme component was provided, wrap the app with it
app_wrappers[(20, "Theme")] = self.theme
+ # Get the env mode.
+ config = get_config()
+
+ if config.react_strict_mode:
+ app_wrappers[(200, "StrictMode")] = StrictMode.create()
+
should_compile = self._should_compile()
for route in self._unevaluated_pages:
@@ -977,9 +984,6 @@ class App(MiddlewareMixin, LifespanMixin):
+ adhoc_steps_without_executor,
)
- # Get the env mode.
- config = get_config()
-
# Store the compile results.
compile_results = []
diff --git a/reflex/components/base/strict_mode.py b/reflex/components/base/strict_mode.py
new file mode 100644
index 000000000..46b01ad87
--- /dev/null
+++ b/reflex/components/base/strict_mode.py
@@ -0,0 +1,10 @@
+"""Module for the StrictMode component."""
+
+from reflex.components.component import Component
+
+
+class StrictMode(Component):
+ """A React strict mode component to enable strict mode for its children."""
+
+ library = "react"
+ tag = "StrictMode"
diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py
index 8330a315c..e79963dc7 100644
--- a/reflex/utils/prerequisites.py
+++ b/reflex/utils/prerequisites.py
@@ -912,7 +912,6 @@ def _update_next_config(
next_config = {
"basePath": config.frontend_path or "",
"compress": config.next_compression,
- "reactStrictMode": config.react_strict_mode,
"trailingSlash": True,
"staticPageGenerationTimeout": config.static_page_generation_timeout,
}
diff --git a/tests/units/test_app.py b/tests/units/test_app.py
index 074e7f2ef..cf49f9d5c 100644
--- a/tests/units/test_app.py
+++ b/tests/units/test_app.py
@@ -1276,12 +1276,23 @@ def compilable_app(tmp_path) -> Generator[tuple[App, Path], None, None]:
yield app, web_dir
-def test_app_wrap_compile_theme(compilable_app: tuple[App, Path]):
+@pytest.mark.parametrize(
+ "react_strict_mode",
+ [True, False],
+)
+def test_app_wrap_compile_theme(
+ react_strict_mode: bool, compilable_app: tuple[App, Path], mocker
+):
"""Test that the radix theme component wraps the app.
Args:
+ react_strict_mode: Whether to use React Strict Mode.
compilable_app: compilable_app fixture.
+ mocker: pytest mocker object.
"""
+ conf = rx.Config(app_name="testing", react_strict_mode=react_strict_mode)
+ mocker.patch("reflex.config._get_config", return_value=conf)
+
app, web_dir = compilable_app
app.theme = rx.theme(accent_color="plum")
app._compile()
@@ -1292,24 +1303,37 @@ def test_app_wrap_compile_theme(compilable_app: tuple[App, Path]):
assert (
"function AppWrap({children}) {"
"return ("
- ""
+ + ("" if react_strict_mode else "")
+ + ""
""
""
"{children}"
""
""
""
- ")"
+ + ("" if react_strict_mode else "")
+ + ")"
"}"
) in "".join(app_js_lines)
-def test_app_wrap_priority(compilable_app: tuple[App, Path]):
+@pytest.mark.parametrize(
+ "react_strict_mode",
+ [True, False],
+)
+def test_app_wrap_priority(
+ react_strict_mode: bool, compilable_app: tuple[App, Path], mocker
+):
"""Test that the app wrap components are wrapped in the correct order.
Args:
+ react_strict_mode: Whether to use React Strict Mode.
compilable_app: compilable_app fixture.
+ mocker: pytest mocker object.
"""
+ conf = rx.Config(app_name="testing", react_strict_mode=react_strict_mode)
+ mocker.patch("reflex.config._get_config", return_value=conf)
+
app, web_dir = compilable_app
class Fragment1(Component):
@@ -1341,8 +1365,7 @@ def test_app_wrap_priority(compilable_app: tuple[App, Path]):
]
assert (
"function AppWrap({children}) {"
- "return ("
- ""
+ "return (" + ("" if react_strict_mode else "") + ""
''
""
""
@@ -1352,8 +1375,7 @@ def test_app_wrap_priority(compilable_app: tuple[App, Path]):
""
""
""
- ""
- ")"
+ "" + ("" if react_strict_mode else "") + ")"
"}"
) in "".join(app_js_lines)
diff --git a/tests/units/test_prerequisites.py b/tests/units/test_prerequisites.py
index 3bd029077..4723d8648 100644
--- a/tests/units/test_prerequisites.py
+++ b/tests/units/test_prerequisites.py
@@ -32,7 +32,7 @@ runner = CliRunner()
app_name="test",
),
False,
- 'module.exports = {basePath: "", compress: true, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+ 'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
),
(
Config(
@@ -40,7 +40,7 @@ runner = CliRunner()
static_page_generation_timeout=30,
),
False,
- 'module.exports = {basePath: "", compress: true, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 30};',
+ 'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 30};',
),
(
Config(
@@ -48,7 +48,7 @@ runner = CliRunner()
next_compression=False,
),
False,
- 'module.exports = {basePath: "", compress: false, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+ 'module.exports = {basePath: "", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60};',
),
(
Config(
@@ -56,7 +56,7 @@ runner = CliRunner()
frontend_path="/test",
),
False,
- 'module.exports = {basePath: "/test", compress: true, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+ 'module.exports = {basePath: "/test", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
),
(
Config(
@@ -65,14 +65,14 @@ runner = CliRunner()
next_compression=False,
),
False,
- 'module.exports = {basePath: "/test", compress: false, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+ 'module.exports = {basePath: "/test", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60};',
),
(
Config(
app_name="test",
),
True,
- 'module.exports = {basePath: "", compress: true, reactStrictMode: true, trailingSlash: true, staticPageGenerationTimeout: 60, output: "export", distDir: "_static"};',
+ 'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, output: "export", distDir: "_static"};',
),
],
)