ReactJS Class Component Rendering Twice - javascript

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/

Related

difference between rfc and rfce in Reactjs

I am new in Reactjs and I want to know what is the difference between "react functional component"
and "react functional component export"?
Here is react functional component code
import React from 'react'
export default function Test() {
return (
<div>Test</div>
)
}
Here is "react functional component export"
import React from 'react'
function Test() {
return (
<div>Test</div>
)
}
export default Test
I want to add more context to your question: I suppose your question comes from the different snippets rfc and rfce of ES7+ React/Redux/React-Native snippets extension in VScode.
Two both cases do the same thing. The differences are the syntax of export. It's not particular to ReactJS but about JavaScript.
1st case: you use export directly before the declaration function line.
2nd case: you declare a function first and later use export with the function's name at the bottom of your code.
I'm used to using 2nd case.
You can read more about export syntax variant + named export vs. default export in this link
You mean the difference between Functional Components And Class Components?
The functions you have shared are the same, both are React Functional Component
React Class Components: is a class component requires you to extend from React Component and create a render function which returns a React element.
example:
import React from 'react'
export default class Test extends React.Component {
render () {
console.log(this.props)
return <div>Test</div>
}
}
React Functional Components: is just a plain JavaScript pure function that accepts props as an argument and returns a React element(JSX)
example:
import React from 'react'
export default function Test(props) {
console.log(props)
return (
<div>Test</div>
)
}

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 Component and render method are called twice

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.

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

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