I'm trying to use react nested elements here, but am I unable to render the third element. The first two react sub-elements work perfectly but the second nested element doesn't render? Why is that so? How should I fix this?
var Nested=React.createClass({
render: function(){
return(
<div className="second">nested div</div>
)
}
});
var Component=React.createClass({
render: function(){
return(
<div className={this.props.className}>
<Nested>
<Nested/> //this doesn't want to render
</Nested>
<Nested/>
</div>
);
}
});
ReactDOM.render(
<div>
<Component/>
</div>,
document.getElementById("app"));
If you want a custom component to render nested components or elements, using {this.props.children} in your custom component's render method will allow you to do that.
Related
I am very new to react and JavaScript and this is my second week of react learning. I am now stuck with the event propagation problem. I have tried to access onClick in the child of <React.Fragment> but event target is seem to be in <React.Fragment> itself. I can not find the simple solution. Please help, Thank you very much in advance.
return (
{loading ? ("...loading...") : data.map(({id,project_title,project_subtitle, project_description,image_url,link},index) => (
<React.Fragment>
<ProjectListButton onClick={(e)=>{ alert(index)}} id={"b"+id} project_title={project_title} project_subtitle={project_subtitle} />
<ProjectPlate project_description = {project_description} image_url ={image_url} link ={link} />
</React.Fragment>
)
)
}
)
<React.Fragment>
is wrapper, to wrap the html elements or sibling elements. It acts as a sudo parent and it just wraps them.
We can't add any attributes to the react fragment.
If you want to capture events, replace fragments with div and add a listener on it. It is not required to use fragment. It is just an option to save an extra element, if we just need them for wrapping purpose.
I have a render() function that returns a div with content inside of it, such as:
return(
<div style={{background: "black"}}>
<[ReactComponent]>
<[AnotherReactComponent]>
...
</[AnotherReactComponent]>
</[ReactComponent]>
</div>
);
When I inspect the element, the outer div does not render, however the ReactComponent does.
maybe you should add some construction like this in the render method of RComponent
<View>{props.children}</View>
I'm migrating an old "jQuery" application, adding some React components. I have some JS/jQuery code adding some elements in the DOM. I want to replace this using for example a new Item component, creating many instances and adding them to the same container. And I need to get the real DOM element to manipulate it (with the old JS/jQuery code).
I found this solution :
const elt1 = ReactDOM.findDOMNode(ReactDOM.render(<CalendarItem item={item} />, container))
but the container content is replaced with the new Item and adding many items, only the last is finally in the container.
I have tried portal :
const elt2 = ReactDOM.createPortal(<CalendarItem item={item} />, container)
but the returned element elt2 is not a DOM element (that I can manipulate after).
Is there a solution to do this ?
Thanks
If you want to manipulate React components using their related DOM elements, look into Refs (https://reactjs.org/docs/refs-and-the-dom.html).
So create the ref in the constructor:
constructor(props) {
super(props);
...
this.calendarItem = React.createRef();
}
And then give the ref to your new CalendarItem:
<CalendarItem item={item} ref={this.calendarItem} />
You can then access the actual DOM node of that CalendarItem using this.calendarItem.current, for example:
$(this.calendarItem.current).focus();
Say I have a vuejs component called child-component which is added to a parent component as follows.
<child-component>
<div>Hello</div>
</child-component>
N.B. this is not the template of the child component. This is how the child component is added to the parent.
How can I get the innerHTML, i.e. <div>Hello</div> in the child component as a string?
Inside the component, child-component, the HTML would be available in the mounted lifecycle handler as this.$el.innerHTML. The parsed vnodes would be available from this.$slots.default.
console.clear()
Vue.component("child-component",{
template: `<div><slot/></div>`,
mounted(){
console.log("HTML", this.$el.innerHTML)
}
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<child-component>
<div>Hello</div>
</child-component>
</div>
You could look at using Vue Child Component Refs. That will let you access the child component's innerHTML from the parent component.
Just add a ref attribute to your child component. It can be anything you choose:
<child-component ref="mychildcomponent">
<div>Hello</div>
</child-component>
Then in the parent methods, you can do something like:
let childEl = this.$refs.mychildcomponent
That will set childEl the entire child component that you've referenced. To get the innerHTML youd just have to go a little further, and do something like this:
let childEl = this.$refs.mychildcomponent.$el.innerHTML
That should give you a string of the child component's innerHTML.
This might help: https://v2.vuejs.org/v2/guide/components.html#Child-Component-Refs
Alternatively if you want to get it from the child component itself, just do the following within a method:
let componentHTML = this.$el.innerHTML
Hope that helps.
I have multiple parent components and within each parent component are nested children components. I'd like to have the class in the nested childrens' component change when a link in that parent component is clicked (a show/hide toggle type thing). I'm guessing this can be done by setting and changing state in the parent component on the click, but am not sure. Is this the correct way to handle this?
Is it usually best practice to hold state in the root component (I should note that the parent component explained above is not the root).
Any and all help is greatly appreciated. Thanks!
Generally, the higher up in your component hierarchy you can push state, the better. Then as the state changes in your parent/root component, new props will trickle down to child components. This makes your child components a lot simpler because they don't have to manage as much of their own state, if any.
In your case, you're exactly right. Handle the click event in your parent which will change your state, then render your child component with the correct className based on that state.
var Child = React.createClass({
render: function () {
return <div {...this.props}></div>;
}
});
var Parent = React.createClass({
handleLinkClick: function (e) {
this.setState({toggle: !this.state.toggle});
},
render: function () {
return <Child className={this.state.toggle ? 'yes' : 'no'} />;
}
});