I am trying to create a custom React component with inline styling using Radium. I have React, Radium and Meteor working perfectly apart of this little thing.
What I want to achieve:
<div style={styles.tile}>
...
var styles = {
tile: {
background: this.props.color
}
And then create new components in the parent like this:
<Tile color="#A200FF"></Tile>
What I get is:
Error: Invariant Violation: findComponentRoot(..., .0.0.0.0.$/=11.0.$=10.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.
Now if I remove this.props.color and type in '#FF0000' it will work perfectly fine. But I really need to be able to pass the color to the component from the parent.
As I said: Meteor, React and Radium are working perfectly fine in other places of the app.
Any ideas how to achieve what I want to build? Is it Radium's bug or is it me not understanding something important about it?
Related
I want to get the height of an element, and the width of Body, so I called
document.style.width
[element].style.height
That returned empty strings, so I got When I call [element].style / document.style I receive this:
CSS list
Why does this happen? ¿Is an issue of React? I'm not using styled components, only css templates with css-loader and style-loader of webpack
You need to think it like a react, here in your sample, you are do that via real dom, and its incorrect, what you need to do, its use useRef
For example:
const imageRef = useRef(null);
<img
ref={(node) => {
imageRef.current = node;
}}
/>
and you can use it like this (like real dom):
imageRef.current.clientHeight
You can read this topic: React Ref and Dom
Probably this is because nowhere as yet in the code have the styles been set (in the sense of element.style.property = value for example in JS, or style="property: value;" inline in the element).
I suspect that the styling is being done through stylesheets and classes.
What you want is to get the current computed stle. Try:
window.getComputedStyle(element);
on the elements you are interested in.
See https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
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
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.
I have a set of components app->page->list_container->list->item
My goal is to notify the app that click happened on item level.
If there is simple relation like parent->child I could use props and do something like: <Child onClick={this._onClick}> ... and then use this.props.onClick() to make a callback.
But what is the best native React-style receipt for doing the same trick with a tree of components? How to notify the app, that item was clicked without calling to Flux/Reflux, Elm and other supported libs?
Standard react way:
Passing onClick function as a prop down your component tree is the standard react-way of doing this.
In <app>:
<page onClick={this._onClick}>
In <page>:
<list_container onClick={this.props.onClick}>
Etcetera.
Or you could use:
<list_container {...this.props}>
To automatically pass down any prop from parent component to the child component.
In a deep tree, this can and will get quite tedious/ lot of work. React was not designed for this purpose.
React is made for (top-down) smart and fast component-tree rendering.
The frameworks for the flux pattern you mention are designed to handle the other interactive functions.
Alternative shortcut (not recommended):
A shortcut you could possibly use is to add a listener directly on the DOM, inside your <app> component, that handles the click event on the item:
In <app> component, add:
componentDidMount: function() {
var itemElementInDOM = document.getElementById('myItem');
itemElementInDOM.addEventListener('click',this._onClick);
}
And in your <item> component, give the item a (unique) id.
I would generally NOT recommend this:
In a typical react tree setup, the lower level components (like
<item>) may be rendered more than once, and then you would need
additional logic to ensure that each ID is unique.
You would also
need to add some additional smarts to make sure you remove the listener if the
item(s) in question are removed from the DOM.