dupe rendering in console react [duplicate] - javascript

This question already has answers here:
Why useEffect running twice and how to handle it well in React?
(2 answers)
React Hooks render twice
(5 answers)
Closed 5 months ago.
Why is this duplicating in the console? I noticed this while working on another projects and noticed the amount of HTML elements I was adding using jQuery was twice as much as expected (building a notification framework). I tried recreating the problem in a new project and the behavior persisted
DupeMountTest.js:
import React, {Component, useEffect} from "react";
const DupeMountTest = () => {
useEffect(() => {
console.log("useEffect")
}, [])
return (
<div>
<p>Test</p>
</div>
)
}
export default DupeMountTest
App.js:
import {
BrowserRouter as Router,
Route, Routes,
} from "react-router-dom";
import DupeMountTest from "./DupeMountTest";
function App() {
return (
<Router>
<div className="App">
<Routes>
<Route path={"/"} exact element={<DupeMountTest/>}/>
</Routes>
</div>
</Router>
);
}
export default App
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Console:
I also attempted this using a class component but "Mounted" also logged twice.
DupeMountTest using class component:
import React, {Component, useEffect} from "react";
class DupeMountTest extends Component {
componentDidMount() {
console.log("Mounted")
}
render() {
return (
<div>
<p>Test</p>
</div>
)
}
}
export default DupeMountTest

Answer provided by evolutionxbox inside the comments section. Problem solved by removing <React.StrictMode> in index.js:
Updated index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// <React.StrictMode>
//
// </React.StrictMode>
<App />
);

React 18 introduces a new development-only check to Strict Mode. This
new check will automatically unmount and remount every component,
whenever a component mounts for the first time, restoring the previous
state on the second mount.
https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors
So, your useEffect is running twice on each mount.
This was put in place to lay the groundwork for future features, so it's not exactly a bad thing.
In the future, we’d like to add a feature that allows React to add and
remove sections of the UI while preserving state. For example, when a
user tabs away from a screen and back, React should be able to
immediately show the previous screen. To do this, React would unmount
and remount trees using the same component state as before.
This feature will give React apps better performance out-of-the-box,
but requires components to be resilient to effects being mounted and
destroyed multiple times. Most effects will work without any changes,
but some effects assume they are only mounted or destroyed once.
It's also discussed in this post (thanks #evolutionxbox):
React Hooks render twice
I really liked a comment there that basically summed up the answer to what you're wondering about:
"it's a feature, not a bug."

Related

Will Redux inside a React component from npm conflict with the container's Redux?

I want to encapsulate a npm React component, and I want to use Redux to manage state inside this React component.
When another React project imports my component, will this React project's redux instance have conflict with my React component?
Here is the example:
The component will look like:
// File Explorer Component, will be build into a npm package
import React from "react";
import { Provider } from "react-redux";
import { store } from "./store";
function FileExplorer({source}) {
<Provider store={store}>
{/* there will be complicated business logic inside */}
</Provider>;
}
Then, I create another React project, and import the FileExplorer component from npm
index.jsx
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { store } from "./store"; // this store is a different one
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Provider store={store}>
<App />
</Provider>
</StrictMode>,
rootElement
);
App.jsx
import FileExplorer from 'file-explorer';
export default function App() {
return (
<div className="App">
<FileExplorer source={'https://example.com/data/v1/files'} />
</div>
);
}
A couple thoughts here.
The first is yes, this would absolutely cause a clash if the components nested inside of <FileExplorer> also need to access the app-wide Redux store, because by default all Redux-connected React components access the same store instance via React context.
It is technically possible to pass an alternate context to <Provider> and create customized versions of useSelector/useDispatch that read the store from that context:
https://react-redux.js.org/using-react-redux/accessing-store#providing-custom-context
although it looks like we don't actually document the API for creating the context-customized versions of the selector hooks atm.
React-Redux should be exporting createSelectorHook and createDispatchHooks functions, which you can see in use here:
https://github.com/reduxjs/react-redux/blob/v7.2.6/src/hooks/useSelector.js#L166
Should be used as:
const useCustomContextSelector = createSelectorHook(MyCustomContext);
All that said: I'd still lean towards tracking the state in a useReducer hook as the default rather than an actual separate Redux store.
Note that you can use RTK's createSlice to create a reducer specifically for use in a useReducer hook - reducer functions are just functions and work fine in either place.

Material UI error while using Grid in React

Code of Login Component:
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
const Login=()=>{
return (
<Grid>
<Paper>
Sign in
</Paper>
</Grid>
)
}
export default Login
Code for App.js
import './App.css';
import Login from './components/Login';
function App() {
return (
<div className="App">
<Login></Login>
</div>
);
}
export default App;
Code for app.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
There's no problem with your code try restart your server it will solve the issue. I am attaching a code sandbox link where you can see it running fine.
Do one thing which is recommended change your app.js to index.js
https://codesandbox.io/s/exciting-thompson-u1rxk?file=/src/index.js

Passing a function from Context to a component to update state in context

I'm having issues passing a function from my context that sets the state inside the context to a component. The function is coming back undefined when I console log it, but everything else in the context shows up when I console log them. It's supposed to update the state of "display" inside my context from the Header component. I've tried finding solutions on stack overflow but nothing has worked so far.
https://codesandbox.io/s/github/joeyjr95/max-kaplan-portfolio/tree/master/?fontsize=14&hidenavigation=1&theme=dark
There was a tiny syntax error in the index. This is how the index should look. Take a look at the PortProvider.
ReactDOM.render(
<BrowserRouter>
<PortProvider>
<App />
</PortProvider>
</BrowserRouter>,
document.getElementById("root"),
console.log(PortProvider)
);
the original:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App/App";
import { BrowserRouter } from "react-router-dom";
import { PortProvider } from "./Context/Context";
ReactDOM.render(
<BrowserRouter>
<PortProvider/>
<App />
<PortProvider/>
</BrowserRouter>,
document.getElementById("root"),
console.log(PortProvider)
);
A few tiny issues, Typo in index.js self-closing <Provider/> and Useless default value, as it is replaced by state. Changed the menu <a> to <div>. Optimized setDisplay, also passed it as toggle then used where required.
<PortContext.Provider value={{ ...this.state, toggle: this.setDisplay }}>
{this.props.children}
</PortContext.Provider>
Fixed Code Sandbox

CSS Path in Reactjs is wrong

I have observed that suddenly CSS path in my project is changed, I am not sure about the reason whether this is a configuration issue or any other, but because of the path CSS is taking too much time to load.
I have already tried to check imports and everything in the code but it seems proper
Please check the below image for path comparison between the new and the backup folder.
New Path:
Old Path
Note: I need the path to be like old where react convert the css to inline, this runs faster.
Below is how I have imported my custom CSS in index.js:
import * as serviceWorker from './serviceWorker';
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { render } from 'react-dom';
import App from './App';
import './index.css';
import './utilities/animate.css';
//react and redux related library
import { Provider } from 'react-redux';
import store from './redux/store/index';
class Main extends Component {
render() {
return (
<Route path='/' component={App} />
);
}
}
let rootElement = document.getElementById('app');
render(<Provider store={store}>
<BrowserRouter >
<Main />
</BrowserRouter>
</Provider>, rootElement);
serviceWorker.unregister();
I have run npm update and updated few packages, may be some of the packages were corrupted or outdated. This fixed my issue of performance and CSS loading slow.

React Router V4 - Route between components and not entire page [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm learning React with React Router V4. I have an image here that might explain what I would like to do:
Click "Next" button
Send click Event to Component A ("button got clicked")
Clicking "Next" would also swap "Component B" with "Component C" while keeping everything the same on the page.
Be able to navigate to a completely different page with different components after all this.
I'm having a really hard time figuring out the routing and structure to be able to handle this.
Thanks for the help.
Does what I'm trying to accomplish here is normal or is this weird and not recommended?
What I tried:
I tried leaving Component A Inside the router on top of everything - this works until you go to page 3 because then I can't remove it.
I've been trying to implement something similar to React Router v4 example on sub-topics. Basically creating a parent component that holds Component A and underneath it have two < Match />, one for Component B and another for Component C. This hasn't worked either and I'm probably doing something very wrong here.
https://react-router.now.sh/basic
I've also been poking around reading many tutorials but they're all different versions of React and React Router. I thought this was simple but been banging my head for a week now without any progress.
Ok I finally figured this out - maybe is not the right/perfect way but it seems to be working. I'll write the code here on how I structured the routing and my components. Remember that this is using react router v4 and things are a bit different that previous versions.
//Router file - index.js
//import React, BrowserRouter, React Dom, Header and Components A, B and C parent
//Create Root component, add BrowserRouter and add a subpath for browserRouter - needed for the nested routes
//Root component renders inside HTML element with an ID of main
//Have a Match for '/' (it will actually be to "/subpath")- then it renders Parent of ABC
import React from 'react';
import { render } from 'react-dom';//instead of importing ALL react dom we just import the render
//React Router V4 uses Match and Miss - if something Matches a path it will render the assigned component and you use Miss for a 404/not found page
import { BrowserRouter, Match, Miss } from 'react-router';
import Header from './components/Header';
import ComponentABCParent from './components/ComponentABCParent';
const Root = () => {
return (
<BrowserRouter basename="/subpathHere">
<div>
<div id="header">
<Header />
</div>
<div className="app-content">
<Match pattern="/" component={ComponentABCParent}/>
<Miss component={NotFound} />
</div>
</div>
</BrowserRouter>
)
}
render(<Root/>, document.getElementById('main'));
//Parent of A, B and C with nested route
//Create parent component - place inside ComponentA and two Match's
//One Match for Component B which is rendered immediately
//Second Match for ComponentC
import React from 'react';
import {Link, Match, Miss} from 'react-router';
import OracleCircle from './ComponentA';
import Intro from './ComponentB';
import StepOne from './ComponentC';
const ComponentABCParent = ({ pathname }) => {
return (
<div>
<ComponentA />
<Match exactly pattern={`${pathname}`} component={ComponentB} />
<Match pattern={`${pathname}component-c`} component={ComponentC}/>
</div>
);
}
export default ComponentABCParent;
//Component B - ComponentB.js
//Inside ComponentB I have a Link that points to ComponentC
import React from 'react';
import {Link} from 'react-router';
const ComponentB = ({pathname}) => {
return (
<div>
<h1>"Stack Overflow is not a tutorial website"</h1>
<Link to={`${pathname}component-c`}>Go to C</Link>
</div>
);
}
export default ComponentB;
//Component C - ComponentC.js
//Render ComponentC with funny answer
import React from 'react';
import {Link} from 'react-router';
const ComponentA = ({pathname}) => {
return (
<div>
<h1>"Your Momma is a tutorial website"</h1>
</div>
);
}
export default ComponentA;
Hope this helps
Maybe something like this would help you accomplish your task.
...
const ComponentA = ({children}) => {
return (
<div>
<div>COMPONENT A</div>
{children}
</div>
)
}
<Route path={/} component={SomeWrapper}>
<Route path={/doubled} component={ComponentA}>
<Route path={/b} component={ComponentB} />
<Route path={/c} component={ComponentC} />
</Route>
<Route path={/single} component={ComponentZ} />
</Route>

Categories

Resources