How to extend a render DOM in react - javascript

Say I have a child class extends from parent class.
Parent class renders
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
In child classes, how could I render a HTML DOM like any of below examples without copy paste?
<div id="container" class="style-scope ">
.....
bunch of DOM.
<div id="childContainer">
</div>
</div>
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
<div id="childContainer">
</div>

Have the parent render it’s children.
render () {
return (
<>
<div id="container" className="style-scope ">
.....
bunch of DOM.
</div>
{ this.props.children }
</>
)
}
Then you can do:
<Parent>
<div id=“childContainer”>...</div>
</Parent>
To get:
<div id="container" class="style-scope ">
.....
bunch of DOM.
</div>
<div id=“childContainer”>...</div>

Related

Vue: Components added through "v-for" ignore flexbox layout

I am trying to have navigation controls displayed horizontally in the upper right hand section of the screen. The following works and displays with each item in a row:
<template>
<div id="navControlPanel">
<div id="controls">
<NavControl />
<NavControl />
<NavControl />
</div>
</div>
</template>
<style>
#navControlPanel{
display: flex;
flex-direction: row;
width: 100px;
height: 50px;
background: purple;
}
#controls{
display: flex;
flex-direction: row;
width: 100%;
}
</style>
yet this does not, and instead displays with them in a column:
<template>
<div id="navControlPanel">
<div id="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
</div>
</template>
NavControl:
<template>
<div id="navControl">
{{control.id}} //Set to just plain text when not dynamically binded
</div>
</template>
<style scoped>
#navControl{
width: 30pt;
height: 30pt;
background: blue;
border-radius: 1000px;
}
</style>
I can't find a logical reason why these would be any different, unless this is some inherent way Vue works that I'm missing.
The issue here seems to be that in the first example you got one div with multiple components in it:
<div id="controls">
<NavControl />
<NavControl />
<NavControl />
</div>
The problem is that in the second example you are creating multiple div elements with the same id and each of them have nested component inside of it.
Here, in a loop, you create multiple div elements with id="controls"
<div id="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
It ends up being something similar to this:
<div id="controls">
<NavControl />
</div>
<div id="controls">
<NavControl />
</div>
<div id="controls">
<NavControl />
</div>
You would probably see it better if you inspected your code in the browser tools.
As a side note: please, keep in mind that if you for whatever reason wanted to do something like this then you would use class instead of id.
Solution:
What you would want to do instead is to create multiple components inside your <div id="controls"></div>.
To do that you would place v-for inside the component and not the outer div.
<NavControl v-for="control in controls" v-bind:control="control" :key="control.id"/>
I am unsure of the actual desired scope, so I will go over both.
If we want multiple controls in the template, as laid out, switch id="controls" to class="controls":
<template>
<div id="navControlPanel">
<div class="controls" v-bind:key="control.id" v-for="control in controls">
<NavControl v-bind:control="control" />
</div>
</div>
</template>
...
.controls {
/* my styles */
}
If the v-for is out of scope, and we only want this ran on those items on NavControl:
<template>
<div id="navControlPanel">
<div class="controls">
<NavControl
v-for="control in controls"
/>
</div>
</div>
</template>

ReactJS Appending Component to Specific ID

I'm having trouble "appending" a child component (NewPageSidear) to a specific ID higher up and outside (Main) the parent component (NewPage) that is loading the child component.
I have the following DOM structure that is created in Main.jsx, which is loaded on page load to index.html:
render(){
return(
<div id="wrapper" className="wrapper">
<Header />
<div id="content" className="content">
<Sidebar />
<div id="main" className="main">
<div className="section-title">
<h2>{this.state.pageTitle}</h2>
</div>
<div id="main-content" className="main-content"></div>
<Footer />
</div>
</div>
</div>
);
}
On page load, I do:
ReactDOM.render(<Dashboard/>,document.querySelector('#main-content'));
ON the Dashboard page, I'll click a button that will execute the following and replace the Dashboard with NewPage:
ReactDOM.render(<NewPage/>,document.querySelector('#main-content'));
My Problem is here:
When NewPage loads, there is a child component, NewPageSidebar that I want to append to #content. If I can get NewPageSidebar to append #content, then I can use componentWillUnmount to remove NewPageSidebar when unmounted. But how do I get NewPageSidebar appended to #content? Any help is very appreciated.
You can do something like:
ReactDOM.render(<NewPage newSidebar={true}/>,document.querySelector('#main-content'));
And in the NewPage:
render(){
return(
<div id="wrapper" className="wrapper">
<Header />
<div id="content" className="content">
<Sidebar />
{this.props.newSidebar ? <NewSidebar /> : null}
<div id="main" className="main">
<div className="section-title">
<h2>{this.state.pageTitle}</h2>
</div>
<div id="main-content" className="main-content"></div>
<Footer />
</div>
</div>
</div>
);
}

React JS :Cannot read property 'dataTransfer' of undefined in children component

i want make a drag-drop app
but a has 1 error here
Cannot read property 'dataTransfer' of undefined in children component
class DragDrop extends Component {
render() {
return (
<div className="Item">
<div className='Start'>
<div id="draggable"
draggable="true"
onDragStart={this.event.dataTransfer.setData('text/plain',null)}>
{this.props.item}</div>
</div>
<div className='div2'></div>
<div className='div2'></div>
</div>
);
}
}
help me !!!
You need to pass a function to onDragStart to access event
onDragStart={(event) => event.dataTransfer.setData('text/plain',null)}
Of course, a better way to handle this is to create a separate function, for readability.
class DragDrop extends Component {
dragFunction(event) {
event.dataTransfer.setData('text/plain', null)
}
render() {
return (
<div className="Item">
<div className='Start'>
<div id="draggable"
draggable="true"
onDragStart={this.dragFunction}>
{this.props.item}</div>
</div>
<div className='div2'></div>
<div className='div2'></div>
</div>
);
}
}

Where should I put an html wrapper element in a React Project?

I am starting with react. So I have this simple project with bootstrap
I want to reuse an HTML structure:
<div className="container">
<div className="row">
<div className="col-lg-8 col-md-10 mx-auto">
{props.children}
</div>
</div>
</div>
So, everytime that I call this structure 3 div's will wrap my child element. right?.
At the beginning I create something like this in my "header" component
const Wrapper = (props) => (
<div className="container">
<div className="row">
<div className="col-lg-8 col-md-10 mx-auto">
{props.children}
</div>
</div>
</div>
)
And was easy to call that element from the class:
function HeaderContent (props) {
return (
<SimpleWrapper>
<div className="col-lg-8 col-md-10 mx-auto">
<div className="site-heading">
<h1>{props.h1title}</h1>
<span className="subheading">{props.spantitle}</span>
</div>
</div>
</SimpleWrapper>
)
}
But now, I want to recall the wrapper from other components. What should I do?
My solution was to create a separate component called: Wrapper.js and declare my wrapper inside it. Is this viable?
thanks, and sorry for the dummy question.
The premise of react is to break down the UI into independent and reusable components, so your proposed solution of adding a 'Wrapper' component is correct.

React: Insert One Component After Another

Very simply I have an HTML structure like this:
<div id="App" class="ui container">
<div id="Keywords" class="left"></div>
<div id="Users" class="right"></div>
<div class="clear"></div>
<div id="Nav"></div>
</div>
And I am appending my components like this:
ReactDom.render(<Feed listenTo="keywords" />, document.querySelector('#Keywords'));
ReactDom.render(<Feed listenTo="users" />, document.querySelector('#Users'));
ReactDom.render(<Nav />, document.querySelector('#Nav'));
I want to get rid of the #Keywords and #Users divs. I just want my components to append to the #App div. I tried something like this:
ReactDom.render(<Feed listenTo="keywords" />, document.querySelector('#App'));
ReactDom.render(<Feed listenTo="users" />, document.querySelector('#App'));
ReactDom.render(<Nav />, document.querySelector('#Nav'));
And I ended up getting this error:
Uncaught Error: Invariant Violation: _registerComponent(...): Target
container is not a DOM element.
Anyone have an idea of how I can just append those two components into the #App div? Do I have to make #App a parent component?
Thanks in advance!
You could do something like this:
let Main = React.createClass({
render: function() {
return <div className="container main">
<Feed listenTo="users" />
<Feed listenTo="keywords" />
<Nav />
</div>;
}
});
React.render(
<Main />,
document.getElementById('app')
);
I have included this fiddle.
It uses the depricated React.render instead of ReactDOM.render - but it seems to work.

Categories

Resources