React: How to render a component twice in a page? - javascript

I have a component build in ReactmyComponent.js
ReactDOM.render(
<MyComponent />,
document.getElementById('my-id')
);
In my Html, I want to render it twice, the HTML is as following:
<div id='my-id></div>
some html
<div id='my-id></div>
I want react render twice in this page, but it only render once for the second div. Is there anyway to render it twice?

You can't have the same id for two or more elements in HTML. Use different ids
<div id='my-id-one></div>
some html
<div id='my-id-two></div>
and call the ReactDOM.render separately for each id.
ReactDOM.render(
<MyComponent />,
document.getElementById('my-id-one')
);
ReactDOM.render(
<MyComponent />,
document.getElementById('my-id-two')
);

It looks like you want to render it in 2 different places, with non-React code in between. To do that, you'll want to give your divs different IDs:
<div id='my-id></div>
some html
<div id='my-other-id></div>
Then render the component to each div:
ReactDOM.render(
<MyComponent />,
document.getElementById('my-id')
);
ReactDOM.render(
<MyComponent />,
document.getElementById('my-other-id')
);

You could do
ReactDOM.render(
<div>
<MyComponent />
<MyComponent />
</div>, document.getElementById('my-id') );
Or You could also have two div tags with different id
<div id='one'></div>
some html
<div id='two'></div>
then
ReactDOM.render(
<MyComponent />,
document.getElementById('one')
);
ReactDOM.render(
<MyComponent />,
document.getElementById('two')
);

Another option is to use a class to define elements to render in:
<div id="my-id-one" class="render-here"></div>
some html
<div id="my-id-two" class="render-here"></div>
Then in js:
let elements = document.getElementsByClassName('render-here');
elements.map(element => ReactDOM.render(
<MyComponent />,
element
));

Related

Removing an external component on click of button

I am new to React. I have the following components in the index.js React DOM area
ReactDOM.render(
<React.StrictMode>
<NavigationBar />
<App />
<Login />
</React.StrictMode>,
document.getElementById('root')
);
The NavigationBar was created using Bootstrap and when I click on the search button, I wanted the component to be removed and replaced by the component.
How do I do it?
you need to use useState :
when you clicked on button you need to change the state with onChange
const [check, setCheck] = useState(false);
ReactDOM.render(
<React.StrictMode>
<NavigationBar />
{check ? <App /> : anotherCoponent you want}
<Login />
</React.StrictMode>,
document.getElementById('root')
);

CDATA block displays as a commented out in React

I'm trying to render some html inside <![CDATA[ ]] block passed to dangerouslySetInnerHTML in ReactJS and this content renders as a commented out. E.g. I get <!--[CDATA[Where is my text?]]--> instead of [CDATA[Where is my text?]] in the DOM.
const HTML_OK = '<pre>My text looks good</pre>'
const HTML_CDATA = '<pre><![CDATA[Where is my text?]]></pre>'
class Hello extends React.Component {
render() {
return <div dangerouslySetInnerHTML={{ __html: this.props.html }} />;
}
}
ReactDOM.render(
<div>
<Hello html={HTML_OK} />
<Hello html={HTML_CDATA} />
</div>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
How can I get <![CDATA[ ]] displays ok in my React application?

How to disable footer in one of the React JS views without creating new layout?

I have about 20 views that use the same layout. Now i need 1 page which does not use footer. First idea i had is to create a new layout but this does not seem like a good way to do this.
LAYOUT
const App = () => (
<div className="full-container">
<Router history={Router}>
<Main>
<STUFF HERE>
</Main>
</Router>
<Footer/>
</div>
);
VIEW
render()
{
return (
<div>
<h1 className="section-smaller-title">TITLE</h1>
<STUFFHERE>
</div>
</div>
);
}
FOOTER COMPONENT
render() {
return (
<footer>
<img alt="footer logo" className="footer-logo" src="imgsurl"/>
</footer>
);
}
}
How can i not show this Footer in that view?
I tried it with
document.getElementByClassName(...)
But this disabled it everywhere.
What is the standard way of doing this?
You can use Conditional Rendering, specifically Inline If with Logical && Operator. Just change your layout to this:
const App = () => (
<div className="full-container">
<Router history={Router}>
<Main>
<STUFF HERE>
</Main>
</Router>
{location.pathname !== “URL path where you don’t want to see footer” && <Footer/>}
</div>
);
More info about Conditional Rendering at https://facebook.github.io/react/docs/conditional-rendering.html#inline-if-with-logical--operator Hope it will help.

Show loading icon before first react app initialization

What is the standard way of showing a loader icon before browser downloads all js files and loads react application.
Can I do something like this without breaking anything?
<div id="content" class="app">
Loading...
</div>
Yes.
Once your javascript has loaded, you can replace Loading... by rendering your react app into the same <div>
render(
<App />,
document.getElementById('content')
);
One way of doing this using component life cycle methods.
class App extends React.Component {
constructor(props){
super(props);
this.state = {
loading: true
};
}
componentWillMount(){
this.setState({loading: true}); //optional
}
componentDidMount(){
this.setState({loading: false})
}
render() {
return (
<section className="content">
{this.state.loading && 'loading...'} {/*You can also use custom loader icon*/}
<p>Your content comes here</p>
{this.props.children}
</section>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app">
</div>

Obtain type of component's children in React

I am using react-router in my app, and it looks something like this:
<Router history={hashHistory}>
<Route path="/" component={Root}>
<Route path="about" component={Child1} />
<Route path="about" component={Child2} />
// and so on...
</Route>
</Router>
I would like to know the type of the child which is passed down to Root each time there is a change. Something like this:
if(typeof this.props.children === Child1) {
// do stuff
}
The children may be of varying types, so if there may be multiple children, you need to check this.props.children[0] and such, not children as a whole. (As you point out in a comment below: props.children is apparently the single child if there is a single child; otherwise, it's an array-like list of children.)
I have no idea if it's documented, but the entry in children appears to have a type property referring to the constructor for the element:
class Child1 extends React.Component {
render() {
return <div>Child1</div>;
}
}
class Child2 extends React.Component {
render() {
return <div>Child2</div>;
}
}
const Main = props => {
const children = "length" in props.children
? Array.from(props.children)
: [props.children];
console.log(`Children in '${props.title}':`);
children.forEach((child, index) => {
console.log(`* ${index}: ${child.type.name}`);
});
return (
<div style={{paddingLeft: "6px"}}>
{props.title}
<div>
{props.children}
</div>
</div>
);
};
ReactDOM.render(
<div>
<Main title="Two children">
<Child1 />
<Child2 />
</Main>
<Main title="One child of type 1">
<Child1 />
</Main>
<Main title="One child of type 2">
<Child2 />
</Main>
</div>,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Categories