React: Invariant Violation (without table) - reactjs

I have looked some answer in stackoveflow. But most of them have something todo with <table> and <tbody>. But my problem is nothing to do with that.
I render this <GISMapDropdownMenu> component using ScriptjsLoader of react-google-maps library.
initialCustomSetup: function() {
let GISMapDropdownMenu = this.refs.cornermenu;
if (googleMapInstance.props.map.controls[google.maps.ControlPosition.TOP_LEFT].j.length === 0) {// push only once
googleMapInstance.props.map.controls[google.maps.ControlPosition.TOP_LEFT].push(GISMapDropdownMenu);
GISMapDropdownMenu.style.zIndex = 1;
GISMapDropdownMenu.style.display = 'inline-block';
}
},
render: function() {
return(
<ScriptjsLoader
**** some setup ****
googleMapElement={
<GoogleMap
ref={googleMap => {
if (googleMap) {
googleMapInstance = googleMap;
layerType = self.props.layerType;
self.initialCustomSetup();
}
return;
}} >
<GISMapDropdownMenu
ref="cornermenu"
availableDesa={self.props.availableDesa}
availableDesaColor={self.props.availableDesaColor} />
{self.props.children}
</GoogleMap>
}
/>);
Here is the implementation of GISMapDropdownMenu.
<div className="gmnoprint GISMap-dropdownmenu" style={{display: 'none'}}>
<div>
<div ref="icon" className="GISMap-dropdownmenu--icon" onClick={this.handleIconClick}>
<img src={BurgerIcon} draggable="false" />
</div>
<div ref="content" className="GISMap-dropdownmenu--content" style={{display: 'none'}}>
<div className="GISMap-dropdownmenu--content_header">
<div className="GISMap-dropdownmenu--content_header__title">List of Desa ({number_of_desa})</div>
<div className="GISMap-dropdownmenu--content_header__cross" onClick={this.handleCrossCLick}>
<img src={CrossIcon} draggable="false" />
</div>
</div>
<div className='GISMap-dropdownmenu--content_list'>
{array_div_element_inrange_assigned_desa}
{array_div_element_inrange_desa}
{array_div_element_assigned_desa}
</div>
</div>
</div>
</div>
{array_div_element_something} is array of this.
<div key={"desa_name-"+desa.desa_name} className={"GISMap-dropdownmenu--content_list__"+desa_color.status}>Desa {desa.desa_name}</div>;
I got this error when use <GISMapDropdownMenu /> component.
Uncaught Error: Invariant Violation: processUpdates(): Unable to find child 97 of element. This probably means the DOM was unexpectedly mutated (e.g., by the browser),
I realised something:
I move the DOM of <GISMapDropdownMenu /> component after mounted. Because I need it to be in the top left of google map.
Any suggestion?

Potential problems: First off, these are guesses as I don't do React all the time, but having said that, here are some possible causes of this:
1) Unmounting components:
This probably means that setState is being called in a callback that was firing after the component that initially started the request has already been unmounted from the dom.
More details on this type of error
2) Having incomplete HTML tags in your markup
For example, adding a <p> tag without the closing </p>. The browser likes all html tags to be complete, so if it doesn't see an end tag for something, it'll add it. Try getting the HTML of your resulting component and comparing it to what you expect. Also remove the child components bit by bit (e.g. remove ) to see when it starts to work so you know what causes this problem. Your html from what I can see doesn't cause this.
3) Build your child components before rendering
Maybe you need to do as this similar answer does
4) Changing the DOM using something other than React
Is your page using jquery or something to change this component in anyway? ie bind events or add/remove anything? If so, this can be causing that as well. Try disabling this and see if it solves the problem
If none of the above help, I'd suggest adding a JSFiddle so people can see what the problem is for sure.

Related

Update dom without refresh the page in react 16

So, I've been looking for a way to render this img tag on my dom without refresh the screen. But I didn't find a definitive answer on how to do that! I mean, in a natural way, with react library and without change a lot of things.
So, when I click this div, it calls a method
<div ref={(ref) => this.refProjectImageCenter = ref} onClick={(e) => this.selectImage(e, this.refProjectImageCenter)} >
<img src="images/projects/new-account.png" alt="new account" />
</div>
And in this method, I update my state with a new img element (not sure if it's the best way to do it tho)
selectImage(e: any , el: HTMLDivElement)
{
e.preventDefault(); // This is not working
this.setState({ selected_img: <img src={el.children[0].getAttribute("src")} /> });
}
And the state will update this part of the DOM
<div className="image detail">
{this.state.selected_img}
</div>
It renders the img indeed, but the page flashes(refresh), and I want to do that asynchronously. It's possible to do that with react? If it's not, how everybody is doing it right now? Thanks a lot.
I found the problem Henry and Shubham. I was updating the css class of the main html tag:
this.refMasterDOM.classList.remove("active");
Inside the method componentWillUpdate(). I removed this line and it stopped refreshing the page with sestate command. Although I don't know why.

React - Why doesn't addEventListener work?

I am trying to create a website by using GatsbyJS, and I got stuck whenever I need to set a onClick event to toggle a class in one of my components. As a beginner with react and gatsby, I'm having a hard time to do it.
So essentially I want to make the following JS code in React/GatsbyJS:
const hamburger = document.querySelector('.burger_menur');
hamburger.addEventListener('click', function(){
this.classList.toggle('open');
});
The following code is my current code in Gatsby component. Have to say, I am using GSAP to make an animation.
This is my code:
import React from 'react';
import { Tween, Timeline } from 'react-gsap';
import '../styles/burger.scss'
const Burger = () => (
<Timeline
target={
<div className='burger'>
<div className='burger_menu'>
<div className='bar half start'></div>
<div className='bar'></div>
<div className='bar half end'></div>
</div>
</div>
}
>
<Tween from={{ opacity: '0', marginRight: '0rem' }} to={{ opacity: '1', marginRight: '5rem' }} ease="Back.easeOut" delay={2}/>
</Timeline>
);
export default Burger
Hopefully someone can help me out with this.
If you're going to go with React, don't manipulate the DOM directly.
More specifically, don't try to act directly on any part of the DOM generated by React.
Here, you're using plain DOM manipulation to attach your event to elements generated by React (also, there's a typo in your class name):
const hamburger = document.querySelector('.burger_menur');
hamburger.addEventListener('click', function(){
this.classList.toggle('open');
});
The thing is, while it may sometimes work, React will regenerate new elements for your menu when it deems it necessary, and your events listeners will be lost.
You have to do it "the React way":
...
<div className='burger'>
<div className={`burger_menu ${this.state.isOpen? ' open' : ''}`} onClick={() => this.setState({ isOpen: !isOpen })}>
<div className='bar half start'></div>
<div className='bar'></div>
<div className='bar half end'></div>
</div>
</div>
...
Don't forget to initialize your state with { isOpen: false }
Clicking the div will toggle this.state.isOpen, which is used to decide whether the class-name will be 'burger_menu' or 'burger_menu open'.
Note: There are more elegant ways to work with classlists when they get longer, but your component being simple and for the sake of clarity, a string template will more than do.
If any of this sounds confusing, please read through the official tutorial Intro To React, it's very well explained and covers everything needed here.
If you're already comfortable with this and want to know more about handling events in React, the docs has you covered once again: Handling Events

Error: Unable to find element with ID 275

I am getting this error when i reload the dynamic page.
Error: Unable to find element with ID 275.
at invariant (invariant.js:38)
at precacheChildNodes (ReactDOMComponentTree.js:96)
at Object.getNodeFromInstance (ReactDOMComponentTree.js:172)
at Object.didPutListener (SimpleEventPlugin.js:210)
at Object.putListener (EventPluginHub.js:143)
at Object.putListener (ReactDOMComponent.js:176)
at CallbackQueue.notifyAll (CallbackQueue.js:76)
at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
at ReactReconcileTransaction.closeAll (Transaction.js:206)
at ReactReconcileTransaction.perform (Transaction.js:153)
and
Uncaught (in promise) TypeError: Cannot read property 'remove' of
undefined
at Object.willDeleteListener (SimpleEventPlugin.js:220)
at Object.deleteAllListeners (EventPluginHub.js:201)
at ReactDOMComponent.unmountComponent (ReactDOMComponent.js:976)
at Object.unmountComponent (ReactReconciler.js:79)
at ReactCompositeComponentWrapper.unmountComponent (ReactCompositeComponent.js:418)
at Object.unmountComponent (ReactReconciler.js:79)
at Object.unmountChildren (ReactChildReconciler.js:146)
at ReactDOMComponent.unmountChildren (ReactMultiChild.js:373)
at ReactDOMComponent.unmountComponent (ReactDOMComponent.js:974)
at Object.unmountComponent (ReactReconciler.js:79)
In this dynamic page i have got a raw html in which i replace the part with #gallery{Id}# with component react-image-gallery. I cannot the problem because in dynamic path where i have got 2 galleries it is working well and with server side navigation and with reloading the page. But in specific dynamic path which using same dynamic component i get this error only on reload, that means if copy the link and paste it to access instantly this page i get this error. By using inspect i see
<div data-reactid="274"> // this is item in children
<p>............</p>
<div data-reactid="275"></div>//but this is another item in children that for unknow reason nested in data-reactid="274"
</div>
but i should see
<div data-reactid="274">
<p>............</p>
</div>
<div data-reactid="275"></div>
I think this happen because of more galleries to add (more data).
The thing is that when i get the array of object to render are the same when i navigating there with server side navigation and when i reload the page. I am getting the array by doing this.
children = parts.map((item, index) => {
if (typeof item === "string") {
return <div key={index} dangerouslySetInnerHTML={{ __html: item }} />
} else {
return <div key={index}>{item}</div>;
}
})
This is due to invalid HTML structure that you are setting via dangerouslySetInnerHTML. Most likely because there is tag that is not closed.
I will share my own experience with this problem to help others:
For me, the issue occurred because i was rendering children through react AND a 3rd party lib
<Mapbox>{mapLoaded ? children : null}</Mapbox>
The map code loads client side only and needs a container div reference so it can inject its <canvas> element after the page has loaded.
By moving the children outside of div reserved for the canvas, react was able to render its own children without being interrupted by nodes injected via 3rd party
<div>
<Mapbox /> {/* <- this element reserverd for canvas / element injection not handled by react */}
{mapLoaded ? children : null}
</div>
If you use a 3rd party lib that performs dom injections it is safer to always render react children outside of it.
If you are using cloudflare make sure HTML minification is disabled since it removes HTML comments that react uses to find elements.
I just burned an hour debugging this issue.
In the end, I had data-reactid attribute on my jsx left over from copying some code out of Chrome Dev tools. I thought I deleted them all, but apparently not. Interestingly, the id number being reported was not the same id hardcoded in the jsx.
react 15.6 with SSR, met this problem with unstructured HTML
<div>
{isValid
?<div>
{value1}
</div>
:{value2}
}
</div>
after warping value2 with <div>:
<div>
{isValid
?<div>
{value1}
</div>
:<div>
{value2}
</div>
}
</div>
Errors 🐛gone

Can only set one of `children` or `props.dangerouslySetInnerHTML`

I'm trying to set the inner HTML of an alert div, but receiving the error message : Can only set one of 'children' or props.dangerouslySetInnerHTML'.
Why does this happen ?
function alertContent(alert) { return {__html: alert.text} }
const Alerts = ({ alerts=[{level: 'warning', text:'<p>Warning message!</p>'}], onDismiss }) => (
<div className="alerts">
{alerts.map(alert =>
<Alert
bsStyle={alert.level}
key={alert.id}
onDismiss={onDismiss}
dangerouslySetInnerHTML={alertContent(alert)}
></Alert>
)}
</div>
)
I had this error message in a react application.
My issue was I had code as below
<p dangerouslySetInnerHTML={{ __html:stringContainingHtml}}> </p>
My issue was the space in the <p> </p> tags - since html gets injected inside these tags the space was causing an issue as it wasn't empty.
Hope this might help some people.
This happens because dangerouslySetInnerHTML can only be applied to one element. In your case, <Alert/> is a complex element made up of multiple children. That being said, the BS Alert component does accept HTML:
<Alert bsStyle="warning">
<strong>Holy guacamole!</strong> Best check yo self, you're not looking too good.
</Alert>
or
<Alert bsStyle="warning">
<span dangerouslySetInnerHTML={alertContent(alert)} />
</Alert>
Solution, You have to make a separate component to render element in which you are using dangerously set.....
For Example:
const RenderHTML = (props) => (<span dangerouslySetInnerHTML={{__html:props.HTML}}></span>)
YourData.map((d,i) => {
return <RenderHTML HTML={d.YOUR_HTML} />
})
you have to close the html tag short hand if there aren't inner HTML
<Alert dang...={} />
instead <Alert></Alert>
I have solved this issue myself.
When you are recursively rendering a component, you must separate out the part of the component where dangerouslySetInnerHTML is being used into another component and then use that component in the one you are recursively rendering.

Invariant Violation when using Link component in a dynamic menu

I'm building a Menu component which renders a list of links which are created using the react-router Link component.
This is the code which renders each item of the menu:
<li
style={{opacity: this.props.isDragging ? 0 : 1}}
className="list">
<Link to={ this.props.list.url }
activeClassName="active"
className={ this.props.owner && 'draggable'}>
<span>{ this.props.list.title }</span>
{ this.props.owner ?
<div className="list-controls">
<span className="glyphicon
glyphicon-pencil"
aria-hidden="true"
onClick={this.setEditMode.bind(this, true)}>
</span>
<span className="glyphicon
glyphicon-remove"
aria-hidden="true"
onClick={this.deleteList.bind(this)}></span>
</div> : null
}
</Link>
</li>;
The menu is dynamic. This means that navigating to another url may re-render the menu with a different list of links. The problem is that when the menu is re-rendered, I get the following exception:
Uncaught Error: Invariant Violation: findComponentRoot(..., .0.0.0.4.$12.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 ``.
I've checked that the .0.0.0.4.$12.0 element is the <a> tag generated by the Link component in the first render.
I've also checked that if I don't use the Link component (and, for example, use a simple <a> tag instead), the exception goes away. Any thoughts?
UPDATE: Apparently the error showed up when I started using react-router-redux (formerly redux-simple-router).
I ran into the same issue on a project using redux-simple-router (now react-router-redux) and was able to fix it by changing which lifecycle methods I was using to dispatch actions (which I was using to rerender a component with different <Link> components).
I created a reduced example in a gist which I got working with this revision.
In the gist there is a <Page> component which dispatches a SYNC action immediately and then a DONE action after 100ms which changes render() to show a loading indicator. Once loaded, the component was rendering some conditional elements, and one of them was a <Link> which was causing the same Invariant Violation.
Originally I was dispatching the actions from within the page's componentWillReceiveProps lifecycle method. When I changed it to componentDidUpdate the error went away. Here's the relevant code that I changed:
- componentWillReceiveProps(nextProps) {
- if (nextProps.params.param !== this.props.params.param) {
- nextProps.dispatch(fetch())
- }
- }
+ componentDidUpdate(prevProps) {
+ if (prevProps.params.param !== this.props.params.param) {
+ this.props.dispatch(fetch())
+ }
+ }
On a side note, I noticed that the error wasn't exclusive to rerendering <Link> components. I was able to recreate the same error when using any element (like a <span> or <a>) with an onClick handler).

Resources