The following is part of my render function in React.
//some code
<div className='icon-container'>
<Icon name='close' />
</div>
While testing this, I have mounted my component. I would like to specifically select the Icon component which is within my icon-container div.
How do I do that?
Note: There could be multiple Icons rendered while mounting in jest. Hence I require specificity. Also, I cannot use shallow since I would like to test the HOC functionality wrapped over the component.
you can use the .find method of enzyme as shown below code
componentWrapper.find(".icon-container [name='close']")
or
componentWrapper.find(".icon-container <use-icon-class-name-or-id>")
Read more about the EnzymeSelector here
Can you explain a title more about what you want to do with that icon, i.e change size, apply animation or what ? I think you don't have to directly inject the Icon component.
Related
In Vue.js, I have a var app = new Vue({...}); and I have a component Vue.component('mycomponent', ... where I can use such component without any issue by directly adding <mycomponent></mycomponent> in html. What I wish to do is to dynamically add those component on demand maybe after a button click or when some other such event takes place. In raw JS, I'd use document.createElement... when event fires and then do el.appendChild.. to add it into html. How would I do the same with Vue.js ?
I'm not doing anything fancy with node js. This is on a single html page with <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> in the <head>.
To do this the "Vue way" usually involves the use of v-if, v-for or <component>, depending on what you want to do:
Use v-if to conditionally show a component/element based on a condition.
Use v-for to render a list of components/elements.
Use <component> to render a dynamic component/element.
So to achieve what you described in your question, you can declare a boolean data property visible like this:
data() {
return {
visible: false
}
}
and use it with v-if to control the visibility of a component in the template:
<mycomponent v-if="visible"></mycomponent>
This requires that <mycomponent> exist in the template upfront. If you don't know what kind of component you want to show, then you can either include each possibility in the template and display the one you want based on some condition:
<comp1 v-if="comp1Visible"></comp1>
<comp2 v-if="comp2Visible"></comp2>
<comp3 v-if="comp3Visible"></comp3>
or you can use <component> together with another data property (comp) which you can set to the name of the component you want to display:
<component v-if="visible" :is="comp"></component>
What you described (document.createElement followed by el.appendChild) does not exist in Vue. Vue has a strict rendering mechanism which you need to work with; it isn't possible to dynamically instantiate components and stick them into the DOM randomly. Technically you can do comp = new Vue() as an equivalent to document.createElement and then el.appendChild(comp.$el), but that probably isn't what you want to do because you would be creating an independent Vue instance that you would have to manage manually with no easy way of passing data around.
I am importing SVG elements into React component, and then rendering them as components.
How do I attach a reference to React Components that contain SVG elements from within my componentDidMount()?
Well, i don't see code example. U can try to use jQuery, when your component render will finish - this is magic stick in many situations. Just type smth like:
let element = $('#element_id');
And you will get access to its information
Hi I am using an UI Library (forced to, company issue..) which provides an Angular component, which renders a form.
Now I want to disable all of the input fields an buttons inside this form. But the component of the library doesn't provide me the possibility to pass a parameter to change the status to read only.
Now I have no other option to do dirty DOM hacking. However it doesn't seem to work.
Here is my HTML of my own component, where I render the Library Component:
<component-of-the-library #formComponent></component-of-the-library>
Now inside my own components class I reference it:
#ViewChild('formComponent', {read: ElementRef}) formComponent: ElementRef;
However when I use the nativeElement feature and the querySelectorAll() function I don't see the button elements:
ngAfterViewInit() {
console.log(this.formComponent.nativeElement);
console.log(this.formComponent.nativeElement.querySelectorAll('button'))
}
The first line outputs the DOM of the library component. There I also see the buttons.
However the second line just returns an empty NodeList.
Am I missing something?
Instead of doing all these, come up with a div overlay and with the size of your form and make show or hide it based on your needs.
It will be easier than disabling each form inputs and buttons. Also the overlay is not the component but your div.
I able to read the DOM Nodes present in the child component from the parent Component using ViewChild() https://stackblitz.com/edit/angular-edmyur?file=src%2Fapp%2Fapp.component.ts
EDIT: I see another problem. AfterViewChecked gets called multiple times...
I found the answer myself. The problem is the LifeCycleHook. AfterViewInit works for your own component, but it doesn't wait for the child components to finish rendering.
When I use AfterViewChecked it works!
However I am still puzzled, that logging the nativeElement has always given me the correct DOM, even though it's still not rendered.
What is the preferred way to toggle (show/hide) a component in React? To my knowledge, there are two ways to do this.
Solution 1:
Conditionally rendering the child component inside the render() method of the parent component.
{
this.state.showUserModal ?
<UsereModal onClose={this.onModalClose} user={this.state.selectedUser}/>
: null
}
Solution 2:
Using a property at the child component which inside its own render() method returns null or the children based on the boolean.
<UsereModal show={this.state.showUserModal} onClose={this.onModalClose} user={this.state.selectedUser}/>
The second solution causes to initialize the component only once (the constructor is called once) and the first solutions do not. I am having issues with this because in need to initialize my state based on the props inside the constructor, so I am forced to use solution 2. But what are the most React way to handle this?
In both cases if the parent state or props are changed both the parent and the child components will be re-rendered. Hence there is no performance gain of the second solution. But if the child component should not be shown in the second case it will be mounted and rendered (but not shown). Taking it into account I would suggest to use the first case.
If you want to persist the DOM elements in the UI, you should go using style binding or class binding:
<UsereModal style={{display: this.state.showUserModal ? 'block' : 'none'}} />
I think the first solution is better since you do not need to initiate UsereModal component with its own state that will control should component be shown or not. I prefer also jsx notation for conditional rendering
{
this.state.showUserModal && <UsereModal onClose={this.onModalClose} user=
{this.state.selectedUser}/>
}
I like to think of Angular components as element directives. Given a component called hero I can use it in the parent template like this:
<hero myparam="something"></hero>
I'd like to use the hero element as a component-managed container, with the component being in charge of the whole element.
EXPECTED
Here's what I hope to get out of the binding from above:
<hero id="component123" class="alien" custom="foo">text</hero>
My custom component transforms the given element and uses it as it sees fit.
ACTUAL
However, it seems the component can only render its template inside the hero element. Best I can get is:
<hero myparam="something">
<div id="component123" class="alien" custom="foo">
text
</div>
</hero>
I feel this is bad because the hero element is not actually the hero, but merly a wrapper for the actual hero. This mixes up the semantics and creates unwanted extra elements.
Is it best practice in Angular to use components as pure wrappers and putting the actual components inside?
Here's an official sample to play around with:
https://plnkr.co/edit/NKjCDS8OEngYHNrBmC5O?p=preview
I like to think of Angular components as element directives.
A component could be thought of as a special kind of directive that updates a template. If you want to change attributes, use an actual directive (attribute directive)
My custom component transforms the given element and uses it as it
sees fit.
When you talk about transforming, you want directives, not components.