React - Router inside a element using class - javascript

How do i render a react component using class?
I have the following code:
class PageLogin extends React.Component {
render() {
return (<p>hello</p>)
}
}
export default PageLogin
When i import it, it render the component entirely, updating the page, so how do i inject it into a div in the component that is rendered?

Ah okay, I think I see what you mean. By default, you can't specify where an individual component is rendered. You tell your main component to render in <div id="id"></div>, so that means EVERY component will use that div as the render root.
However, as of React v16 you can use ReactDOM.createPortal to render a component in any element.
class PageLogin extends React.Component {
render() {
return (
<div>
{ReactDOM.createPortal(<p>hello</p>, document.getElementById('anotherRoot'))}
</div>
)
}
}
export default PageLogin
Ideally though, you'd want to move that code to wherever you are rendering PageLogin:
render() {
return (
<div>
{ReactDOM.createPortal(<PageLogin />, document.getElementById('anotherRoot'))}
</div>
)
}

Related

Inserting a element into REACT child

I am rendering a chart with react, and I would like to add an element to the title of that chart. Unfortunately, I am using a shared chart component, and majorly modifying the component would be difficult to justify.
I have tried using refs; however, I'm running into difficulty figuring how to actually append a virtual dom element as a child element.
Specific Chart Class:
class ChartWithInfo extends React.Component {
constructor(props){
super(props);
this.chartWrapperElement = React.createRef();
}
componentDidMount() {
const infoInsertion = (
<div>
<IconButton/>
</div>
)
this.chartWrapperElement.current.insertBefore(infoInsertion, this.chartWrapperElement.current.firstChild);
}
render() {
return (
<GenericChart
variables={this.props.variables}
ref={this.chartWrapperElement}
/>
);
}
}
Generic Chart Class
export default class EmbeddedChart extends PureComponent {
// Random methods //
render() {
return (
<div ref={this.props.ref} id={'chartDiv'}>
Chart
</div>
);
}
}
The expected result would essentially be:
<div id='chartDiv'>
<IconButton/>
</div>
What is the most react way to do this? Am I missing something with refs?
React is meant for components and if you follow the separation of concern and component architecture. You can segregate all your components and individual reusable components. Create your button component separately and import anywhere else. Bind your events and business logic respectively.

How to properly create and render functional components?

I am attempting to create and render a functional component using the instructions here as a base. From what I've sen in there I should be able to do something along the lines of:
class MyComponent extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
)}
function OtherComponent(props) {
return (
<div>
test
</div>
);
}
}
But this throws the error:
Unexpected token: function OtherComponent(props) {
^
I found a few posts that suggested removing the function so I tried that but then it throws the error:
OtherComponent is not defined
I'm able to get it working by creating a separate class component like so:
class OtherComponent extends React.Component {
render() {
But that's not what I want to do. What is the proper way to create/render a functional component in React.js?
For example this one works. See the docs ;)
React - Composing Components
function OtherComponent(props) {
return <div>test</div>;
}
class App extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
);
}
}
Try this
class MyComponent extends React.Component {
OtherComponent = (props) => {
return (
<div>
test
</div>
);
}
render() {
return (
<div>
{this.OtherComponent("test")}
</div>
)}
}
You can't define a component inside of another component. A functional component means that the component is created from a function and is not a class. It can't have it's own state, because the state is initialized in class constructor. Check out this article for more info https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc
const otherComponent = (props) =>
<div>
test
</div>;
Here is another way. Its not correct to declare a component in a render function. If it is used solely in a parent component why not make that explicit and use static
class MyComponent extends React.Component {
static myOtherComponent = (props) => <div>{'test'}</div>
render(){
return(
<div>
<MyComponent.myOtherComponent {props} />
</div>
)
}
The myOtherComponent behaviour is controlled purely through the props it gets , it won't have its own state.
Or you could just make it a separate component e.g
export default myOtherComponent = (props) => ()
and import it into MyComponent. Please note , now with hooks ( see React Docs ), you can use hooks to mimic state etc in functional components and the latter approach might be your cleanest and most flexible approach.
This way you can define a function component
function OtherComponent(props) {
return <div>{props}</div>;
}
And now you can use functional component in your App (class component) like below
class App extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
);
}
}

How to consider defining a functional component inside a class component and outside the class in React?

Considering the following three places of defining a functional component in React -
Inside a class (outside the render method)
Inside a class (inside the render method)
Outside the class
In the sample code below, funcComponent1, funcComponent2 and funcComponent3 are defined in the three different locations. How do I consider when to define a functional component in any of these 3 places?
import React, { Component } from 'react';
const FuncComponent1 = (props) => {
return (
<p>{props.name}</p>
)
}
class TestComponent extends Component {
constructor(props){
super(props);
this.state = {
name: "JavaScript"
}
}
FuncComponent2 = (text) => {
return (
<p>{text}, {this.state.name}</p>
)
}
render(){
const FuncComponent3 = (props) => {
return (
<p>{props.text}, {this.state.name}</p>
)
}
return (
<div>
<FuncComponent1 name={'Abrar'} text={'Hello World'}/>
<FuncComponent3 text={"HEllo World"}/>
</div>
)
}
}
export default TestComponent;
You must avoid using functional component inside of render since they will be recreated on every render.
As far as using functions that return JSX inside Class component but outside render` is considered, you can do that when you want to make use of the state or props of the class in order to render JSX content but that which is very specific to the particular class
A functional component outside of React component is most advantageous when the same component can be used at multiple places and hence it makes sense to pass props to it and render it.

How to add a class on React component mount?

My React app has a base div like so:
<body>
<div id="root">
....
</div>
</body>
In my Welcome container, I would like to add a class to the div w id="root and then on Welcome container unmount, remove the class.
class Welcome extends React.Component {
componentDidMount() {
console.log('componentDidMount');
console.log($('#root'));
}
....
With jQuery I could do something like
$('#root').addClass('myClass')
....
$('#root').removeClass('myClass')
What is the equivalent in React for adding and removing a class on a div after finding it by its ID?
This makes no sense. You shouldn't be adding classes to root from React components. The root div should just exist to inject React in to using ReactDOM.
Instead of modifying the html root, create a react class called App or something and render a <div className="app" /> that wraps all of your components. You can then use React state or props to modify the className.
class App extends React.Component {
constructor() {
super();
this.state = {
appClass: 'myClass'
};
}
componentDidMount() {
this.setState({ appClass: 'newClass' });
}
render() {
return (
<div className={this.state.appClass}>
// Render children here
</div>
);
}
}
If you want to modify the appClass from a child component such as Welcome which is further down in your application then you will need to use a state management like Redux or Flux to modify the className from a child component otherwise it will get messy fast.
EDIT: removed semicolon from this.state object

React component setting the onClick of it's child ... how to make it work for all kinds of children

I have a react component that wraps another, and sets the child's onClick like this:
class OutstandingActionForm extends Component {
render() {
return (
<div className="outstanding-actions">
{React.cloneElement(this.props.children, {onClick : this.openForm})}
It basically lets the parent (OutstandingActionForm) open a modal if the child (whatever it is) is clicked, and separates the appearance of the click-target from the behaviour of the thing that opens.
This works fine if the child is an <img>:
<OutstandingActionForm actions={this.props.actions}>
<img src={'/assets/notification.jpg'} className="notification-icon"/>
</OutstandingActionForm>
In this case, the OutstandingActionForm opens if the notification.jpg <img> is clicked.
However, for some reason it doesn't work if the child component is itself a react component:
<OutstandingActionForm actions={this.props.actions}>
<OutstandingActionsSummary/>
</OutstandingActionForm>
Even if OustandingActionSummary is itself just an image:
class OutstandingActionsSummary extends Component {
render() {
return (
<img src={'/assets/notification.jpg'} className="notification-icon"/>
)
}
Why is this so? How could I achieve the same when wrapping a react component as when wrapping the native <img> tag?
<img> knows how to use onClick. But <OutstandingActionsSummary> doesn't! In the implementation of <OutstandingActionsSummary>, you have to specify how to use the property. It should look like:
class OutstandingActionsSummary extends Component {
render() {
return <img onClick={this.props.onClick}/>
}
class OutstandingActionsSummary extends Component {
static defaultProps ={
onClick:function(){}
}
render() {
return (
<img onClick={()=>this.props.onClick()} src={'/assets/notification.jpg'} className="notification-icon"/>
)
}
OutstandingActionsSummary doesnot support onClick,add it.
In OutstandingActionForm use only {this.props.children} and attach click handler on OutstandingActionsSummary and call its parent OutstandingActionForm to process.

Categories

Resources