React tutorial not displaying the div - reactjs

Im a started with Reactjs and built my initial div but for some reason it does not display the div.
Here is the code displayed
helloworld.js content:
React.render(
React.createElement('h1',null,'Hello World')
,document.getElementById('divContainer')
)
Console error:
react.render is not a function.
React version used:
React v15.0.1

Please use ReactDOM.render() function

You need to import React like so:
import React from 'react';
You need to import the library called React. Also, React.render() is deprecated, you need to use ReactDOM.render().
To take a component and render it to the DOM has been a separate library called ReactDOM. You don't use React with render(), you use ReactDOM. In order to use it you also have to import it like so:
import ReactDOM from 'react-dom';
Then you can implement:
ReactDOM.render(App);
But that is not all. You have not shown us the whole code to your component, but you need to instantiate your component before rendering. What you showed seems to be the transpiled version from Babel, but even that seems not quite right, it would look like this:
var App = function App() {
return React.createElement(
"h1",
null,
"Hello World"
);
};
ReactDOM.render(React.createElement(App, null));
And the above code would be based off creating an instance of App.
This is a class: App of a component, it produces instances. To make an instance, you just wrap it in jsx tags like soL <App />.
Last but not least you need to put it in the page or DOM via the second argument which is a target container. When you render the component <App />, produce some HTML into this element that exists in our HTML document, so then your code, going by your transpiled version that you shared here would look like this:
var App = function App() {
return React.createElement(
'h1',
null,
'Hello World'
);
};
ReactDOM.render(React.createElement(App, null), document.querySelector('.container'));

Related

Is there any way to fix errors caused by Bootstrap when upgrading to React 18

I am following a guide to upgrade to React 18. After completing the upgrade I am seeing errors on certain pages in my app.
ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18.
I am not using the unstable_renderSubtreeIntoContainer() function anywhere in my app, but when I look closer at what is causing these errors it seems to be caused my Bootstrap components.
Is there anyway to update this to remove the errors?
I ran into the same problem with react-bootstrap#v0.33.1 specifically when using OverlayTrigger component after upgrading to React 18. The warning message suggests to migrate to using portals. So I implemented a CustomOverlayTrigger component that leverages portals and referred to React's portal documentation to do so. Note that this solution is for Bootstrap 3 usage of OverlayTrigger (react-bootstrap v0.33.1). It seems later versions of react-bootstrap got rid of using ReactDOM.unstable_renderSubtreeIntoContainer. If you are not in a position to migrate to later versions (like I am), this solution will help for this use case. I have not check thoroughly if other components use the deprecated method, but the approach might be the same.
First of all, I copied the original source of the OverlayTrigger component code located here. You will need to clean up the imports and include into your code the utils function createChainedFunction located here.
I then created a portal wrapper based off React's documentation that looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
const tooltipRoot = document.getElementById('tooltip-root');
class PortalWrapper extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
tooltipRoot.appendChild(this.el);
}
componentWillUnmount() {
tooltipRoot.removeChild(this.el);
}
render() {
// eslint-disable-next-line react/destructuring-assignment
return ReactDOM.createPortal(this.props.children, this.el);
}
}
PortalWrapper.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
};
export default PortalWrapper;
At the top, you can see the line const tooltipRoot = document.getElementById('tooltip-root');, I simply added in my index.html a div next to the react app's root div that will server as the anchor for my portal.
Then, back in the CustomOverlayTrigger component copied from react-bootstrap, I edited it in the follwing manner:
Remove all references to this._overlay and this._mountNode because the PortalWrapper now manages the mounting/unmounting. So I deleted componentDidMount(), componentDidUpdate(), componentWillUnmount() and renderOverlay()
I modified makeOverlay so that its result is wrapped by PortalWrapper so it became the following:
makeOverlay(overlay, props) {
return (
<PortalWrapper>
<Overlay
{...props}
show={this.state.show}
onHide={this.handleHide}
target={this}
>
{overlay}
</Overlay>
</PortalWrapper>
);
}
Finally, I changed the render method's return statement to become:
return (<>
{cloneElement(child, triggerProps)}
{this.makeOverlay(overlay, props)}
</>);
After this, I simply had to replace all my invocations to OverlayTrigger with CustomOverlayTrigger and I had the same result without the warning message.

Custom webcomponent from library in React

I have a React application which should use the following library:
MICO-grapheditor
And I want to write this code:
render() {
var webgraph = require("#ustutt/grapheditor-webcomponent");
GraphEditor.
return (
<network-graph classes="red blue" mode="layout" zoom="both">
<style slot="style">
svg {width:100%; height: 100%}
</style>
<svg slot="graph"></svg>
</network-graph>
)
}}
But I get the following:
TS2339: Property 'network-graph' does not exist on type 'JSX.IntrinsicElements'.
How can I resolve this error?
At least the expression
var webgraph = require("#ustutt/grapheditor-webcomponent");
should come up before the rendering. Also, doing CSS in HTML and Node.js/React is not pretty much the same. Or is it?
React is likely assuming that network-graph is a React component, thus it expects that the attributes you are using (mode and zoom) are defined in a React component. Also React uses className instead of classes.
When you write between <network-graph> tags this content is considered as a group of child nodes that can be used by the network-graph component in the following way:
import React, { Component } from "react";
class NetworkGraph extends Component {
render() {
const {mode, zoom, children} = this.props;
return (
<>{children}</>
); // children would contain the <svg>
}
}
When you require MICO-grapheditor, you are not importing a React component, but a web component instead, even though React tries to interpret it...
Also, avoid shoving in <style> tags in the render's return. CSS styles in React may be imported to components like so import './my-styles.css';.

component syntax in React

I'm a beginner in React, just some questions about component
Let's say I have a component :
function HelloWorld() {
return React.createElement('div', {}, 'Hello World!')
}
so my questions are:
1- HelloWorld is the component name, isn't it?
2- then I have the code below:
ReactDOM.render(
<HelloWorld/>, document.querySelector('#root')
);
what's the syntax of <ComponentName/>? isn't that more sensible to have the render function to be like:
ReactDOM.render(
HelloWorld(), document.querySelector('#root')
);
syntax of ReactDOM.render this :
ReactDOM.render( <Component />, id of DOM element where component will render );
in React there are 2 types of components :
1) functional components (also called stateless components)
2) class components (also called as stateful components
example of functional component :
function HelloWorld() {
return React.createElement('div', {}, 'Hello World!')
}
or
const HelloWorld=()=>{
return (<div>HelloWorld</div>);
}
export default HelloWorld;
example of class component :
class HelloWorld extends React.Component{
render(){
return (<div>HelloWorld</div>);
}
}
so passing component like this :
ReactDOM.render(
HelloWorld(), document.querySelector('#root')
);
is not correct way , in React you use Component as <ComponentName />
so thats why you have to pass like this :
ReactDOM.render(
<HelloWorld/>, document.querySelector('#root')
);
1 - No, that would be the contents (aka "children") of the div tag you are creating. That is <div>Hello World!</div>.
2 - Not sure what the ComponentName you are referring to is. The snippet takes the HelloWorld React component and mounts it to the DOM, which also starts the Reconciliation process.
Also, the purpose of JSX is to have a syntactic sugar that resembles HTML as much as possible. Yes, what you are suggesting is basically what happens behind the scenes (from a pseudo-code point of view), but would defeat the purpose of using JSX.
When react builds your app and run, it will be something like the last example that you gave.
React compile all components to
React.createElement('htmlTag' || someOtherComponent(), ...);
So a lot of people find more easy and productive to write your components using the JSX sintax and just use the build command to compile and bundle the code.

How to know when React built-in component finished rendering?

I'm using a React rendered SVG from a file.
import React from 'react';
import {ReactComponent as SvgFrontPanel} from '../svg/panel.svg';
render() {
return (<div className="panel">
<h2>Panel</h2>
<SvgFrontPanel/>
</div>);
}
After svg is rendered I need to execute some init code for it. I can do it once via window.onload or documentReady or whatever usual way to check when the page is ready. But then, when this component gets unmounted/mounted, I cannot catch the moment.
I can use componentDidMount or put my code inside render of this component but it doesn't mean the svg inside SvgFrontPanel is rendered at the time.
So here is the question: how can I understand when some uncontrolled component finished rendering? Suppose I cannot modify svg file at all (actually I can but prefer not to).

React CSS Modules and testing the component

Inside my code I use babel-plugin-react-css-modules which is practically the same as react-css-modules
I have a code like this inside react component.
styleName is for CSS Modules and I define styles for them inside countdownForm.local.scss
className represent my Bootstrap classes
import './countdownForm.local.scss'
class CountdownForm extends Component {
...
render () {
return (
<div styleName="first" className="container">
...
</div>
)
}
}
To test this component inside my test I have to use ignore-styles package because JavaScript can't handle CSS syntax and when we run unit tests, the test will try to import the CSS file without Webpack which will result error.
import register from 'ignore-styles'
import React from 'react'
import test from 'tape'
import CountdownForm from 'CountdownForm'
register(undefined, () => ({styleName: 'fake_class_name'}))
test('CountdownForm => should exist', (t) => {
t.ok(CountdownForm)
t.end()
})
By doing this everything passes great and test works without problem but I always get this warning in the console
Warning: Unknown prop styleName on tag. Remove this prop from
the element.
It is not a problem of functionality because tests works but it is annoying to get this message every time I run tests. How to fix, get rid of it?
The warning is because you are not running the babel-plugin-react-css-modules compilation step before the test.
That works by replacing styleName prop with the computed CSS modules class names. Therefore styleName is never actually passed to the div in your real build (https://github.com/gajus/babel-plugin-react-css-modules#how-does-it-work). It would rewrite your component to something like...
class CountdownForm extends Component {
...
render () {
return (
<div className="container CountdownForm_first_123xyz">
...
</div>
)
}
}
In your test, without running the babel plugin first, you will successfully manage to ignore the CSS import via ignore-styles but the props replacement hasn't happened so you end up passing a styleName prop to the div, which is not a defined property for div component, so React will warn you
Best way to fix this would be to run a babel compilation step before the test, that way you can also test the real localised classnames assignment

Resources