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

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

Related

Rendering a dynamically loaded React component

`Here is my attempt to dynamically load a component at the click of a button, and show on page.
https://codesandbox.io/s/sweet-haze-knste?file=/src/App.tsx
I am using the below line of code to dynamically import the component when button is clicked.
const importedComponent = React.lazy(() => import("./DynamicallyImportedComponent"));
And the state is set using
this.setState({
importModule: importedComponent
// importModule: CommonEditorCallout
});
However, this does not render correctly.
When I use the regular import using the below, it renders fine
import DynamicallyImportedComponent from "./DynamicallyImportedComponent";
Is this possibly due to the fact that in the regular import I specify the name of the component I am importing, or something to do with the dynamic import itself?
Docs
The lazy component should then be rendered inside a Suspense component, which allows us to show some fallback content (such as a loading indicator) while we’re waiting for the lazy component to load.
So wrapping your lazy loaded component with React.Suspense with a fallback props will fix the error.
<React.Suspense fallback={<div>Loading...</div>}>
{this.state.showImportedModule && <div>{<ComponentToShow />}</div>}
</React.Suspense>
See example

How to import FooterCaption from 'react-images'?

I am trying to use the library 'react-images' in my reactjs project. I am receiving the error "Unexpected token" in the react-images\src\components\Footer.js file. Also, on the same line i have the error "'import ... =' can only be used in a .ts file.".
import type { PropsWithStyles, ViewType } from '../types';
Also, I am receiving the error "'type aliases' can only be used in a .ts file." in many of the component files in 'react-images' library. Why is this? Thanks.
import React, { Component, Fragment } from 'react';
import Carousel, { Modal, ModalGateway, FooterCaption } from 'react-images';
You misunderstand how this library is designed. If you look at the documentation, FooterCaption is listed under Component API. That means FooterCaption is part of the API for the Carousel component meaning that this is designed with the Slots Pattern.
If you look at the example code above it, it shows you how this works.
<Carousel components={{ Header: CustomHeader }} />
The Carousel component has a prop called components which takes an object. This object is expected to have keys that are one of the various replaceable components listed under Component API. The value is expected to be a something that React can render; typically a component. This example is replacing the Header with a custom header component called CustomHeader.
If you don't override the component, then Carousel will render something by default as described in the documentation for each component under Component API.
If you would like to override the default FooterCaption, then you will do something like this:
<Carousel components={{ FooterCaption: MyCustomFooterCaption }} />
Where MyCustomFooterCaption is a component you've defined elsewhere. The props it will receive from the Carousel component can be found in the source code.
To summarize:
You don't need to import FooterCaption.
If you plan on overriding the default FooterCaption, then create your own component and pass it in as shown in example.
The same goes for everything listed under Component API.

React redirect on click of svg element

I have a single page React App that is d3 and SVG heavy, and I would like to be able to redirect from one page to another when a user clicks on an svg rect on one of my pages. I am familiar with this.props.history.push() as well as the <Link> component from the react-router-dom library, however neither of these seem to help in this instance.
The svg element of relevance here is deep in a graphing component of mine that is 3-4 children down from the front-end's main App.js file that does all of the routing, and when I run console.log(this.props) in my component with the svg, there is no history object on the props. I'm not sure if a reproducible example is needed here, as I just need direction.
In short, I have no idea what should go into the on-click function that is associated with my svg rect, to enable redirect in my app. Any thoughts on this would be greatly appreciated!
Edit: obviously this is wrong but i tried to return a Redirect component in on-click handler and it didn't work:
...
...
function handleMouseClick() {
console.log('clicked')
return <Redirect to='/stats' />;
}
myRect.on('click', handleMouseClick)
...
Edit2: should i put the rect elements inside of components in the svg? is that even possible?
You can add the history prop from react-router to a component by wrapping it with withRouter. Just make sure whatever is mounting your component is using the wrapped version (usually by only exporting the wrapped component).
import React from 'react';
import { withRouter } from 'react-router';
class MyComponent extends React.Component {
render() {
return (
<button onClick={() => this.props.history.push('/newpage')}>
Click me
</button>
);
}
}
export default withRouter(MyComponent);

Can we have React 16 Portal functionality React Native?

I'm using React Native which ships with React 16 alpha release which supports portals. While in browser and having access to DOM we can use id or classes to access element from anywhere in component/file hierarchy like this:
const modalRoot = document.getElementById('modal-root');
and pass it to createPortal(child, container) container arg. React docs clearly says than container should be DOM element:
The second argument (container) is a DOM element.
This function is also a method of ReactDOM which doesn't exist in React Native.
Is there a way to achieve the similar functionality in React Native?
Use case:
I want to render an animated overlay in the root of my application but pass the Animated values props to it from a parent deep in the tree hierarchy (can't use Redux actions for such things).
I had similar problem where I wanted to render overlay on top of everything from deeply nested child component. I solved my problem with React Native's Modal
It renders its content on top of everything :) Easy to use and no need for extra dependencies
I don't think react-native provides this functionality in its own API.
But there is a library available which provides the similar functionality. react-gateway
As per the docs of react-gateway,
It also works in universal (isomorphic) React applications without any additional setup and in React Native applications.
React Gateway does not directly depend on react-dom, so it works fine with React Native under one condition:
You must pass React Native component like View or similar to component prop of .
import React from 'react';
import { Text, View } from 'react-native';
import {
Gateway,
GatewayDest,
GatewayProvider
} from 'react-gateway';
export default class Application extends React.Component {
render() {
return (
<GatewayProvider>
<View>
<Text>React Gateway Native Example</Text>
<View>
<Gateway into="one">
<Text>Text rendered elsewhere</Text>
</Gateway>
</View>
<GatewayDest name="one" component={View} />
</View>
</GatewayProvider>
);
}
}
The above example is taken from the repo itself. react native example
One way to render the items above the screen can be done using react-native-paper library.
import * as React from 'react';
import { Text } from 'react-native';
import { Portal } from 'react-native-paper';
const MyComponent = () => (
<Portal.Host>
<Text>Content of the app</Text>
</Portal.Host>
);
export default MyComponent;
Portal host renders all of its children Portal elements. For example, you can wrap a screen in Portal.Host to render items above the screen.
Here is the link which describes its usage:
https://callstack.github.io/react-native-paper/portal-host.html

React tutorial not displaying the div

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'));

Resources