React Component and render method are called twice - javascript

In my component Constructor and render method are called twice. I created a brand new project from create-react-app, it only one component other than App component so it is not so complex and complicated but still the problem persists.
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import First from "./First";
function App() {
return (
<div className="App">
<First />
</div>
);
}
export default App;
import React, { Component } from "react";
class First extends Component {
static count = 0;
constructor(props) {
super(props);
this.state = {};
console.log("ctor");
alert("ctor");
}
render() {
First.count++;
console.log("Render method", First.count);
return <div>Hello World</div>;
}
}
export default First;
All other lifecycle hooks are being rendered once, no issues with them.

it's probably because of React StrictMode in your index.js file.
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
strict mode checks for potential problems and it caused to run some lifecycle methods (like constructor, render, componentShouldUpdate, etc) twice.
if it bugs you, you can simply remove it but better to don't.
Strict mode checks are run in development mode only; they do not impact the production build.
you can read more about it on strict-mode

your code is just fine Constructor and render method are called only once i have tried in my machine.

Related

dupe rendering in console react [duplicate]

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."

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.

React JS, props validation

New to React JS, props validation practise as follows:
import React from 'react';
import PropTypes from 'prop-types';
class App extends React.Component {
render() {
return (
<div>
<h3>String : {this.props.propstring}</h3>
</div>
);
}
}
App.propTypes = {
propstring : PropTypes.string
}
App.defaultProps = {
propstring : "My Name"
}
export default App;
import React, { component } from 'react';
import ReactDOM from 'react-dom';
import App from './AppProp.js';
ReactDOM.render(<App />,document.getElementById('root'));
Getting an error as:
TypeError: Class extends value undefined is not a constructor or null.
What am I missing here and how can I resolve the above error?
There are 2 possible problems. Most probably you're importing { component }(like you do in your index file, which is wrong), instead of { Component } somewhere in your code and trying to extend component which doesn't exist.
The other reason is that you might be circularly importing classes, but I doubt it. Also, is your file called AppProp.js?
Post the stack trace and it would also help if you post all the components you're using. Post your package.json as well, as you might be using wrong absolute paths.
The code is perfectly fine. I executed it on my local machine and it ran fine.
The only issue you may be facing is to with
circularly importing classes, which is apparently a limitation
Know more from the resource:
https://esdiscuss.org/topic/how-to-solve-this-basic-es6-module-circular-dependency-problem

ReactJS Class Component Rendering Twice

Very simple example: My App.js file reads
import React from 'react';
import Test from './component/Test';
function App() {
return (
<div className="App">
<Test/>
</div>
)
}
export default App;
and my Test.js file reads
import React, { Component } from 'react'
class Test extends Component {
render() {
console.log('rendered')
return null
}
}
export default Test
In the console, 'rendered' is always printed twice. Why?
The reason is React.StrictMode.
React.StrictMode is a wrapper introduced in version 16.3.0 back in 2018 and in 16.8.0 it is applied also for hooks.
Code:
Check index.js for the below code
<React.StrictMode>
<App />
</React.StrictMode>
React.StrictMode
cannot spot side-effects at once, but it can help us find them by intentionally invoking twice some key functions.
These functions are:
Class component constructor, render, and shouldComponentUpdate methods
Class component static getDerivedStateFromProps method
Function component bodies
State updater functions (the first argument to setState)
Functions passed to useState, useMemo, or useReducer
Please check this blog
https://mariosfakiolas.com/blog/my-react-components-render-twice-and-drive-me-crazy/

ReactJS - Can't import component

I'm brand new to ReactJS. I'm developing a little single page app and I'm just trying to create my components to import within my main component.
TestComponent.jsx
import React from 'react'
export class TestComponent extends React.Component {
render() {
return (
<div className="content">Test Component</div>
)
}
}
Inside my main.jsx I've imported this component calling
import TestComponent from './components/TestComponent.jsx'
Then I've tried to call my component for a specific route:
render(
(<Router history={history}>
<Route path="/" component={NavMenu}>
<IndexRoute component={Index}/>
<Route path="test" component={TestComponent}></Route>
</Route>
</Router>),
document.getElementById('main')
)
I've not got any errors from the console, but I don't see my component. What am I doing wrong?
The import syntax without curly braces is for importing default exports, not for importing named exports.
Make your component the default export:
TestComponent.jsx
import React from 'react'
export default class TestComponent extends React.Component {
render() {
return (
<div className="content">Test Component</div>
)
}
}
Alternatively you should be able to import it as it is with the following import statement:
import { TestComponent } from './components/TestComponent.jsx'
You might want to read up on ES6 modules (e.g. in Exploring ES6) if you want to use ES6 in your React code.
Make sure to include semicolons after the import statements too. you might get away with a browser (or environment like Node) reading the code in some cases, but the import function runs right into your export in this code.
.js should have the first letter capital. Else import will not take place.

Categories

Resources