Having an issue where a 3rd party library is setting document.body.innerHTML, and that causes setState to stop seeming to work fully. In React tools in chrome and when debugging it updates the state object correctly, but the rendered output does not update.
Cannot figure out what is going on here, no error occurs, stepping through the debugger nothing stands out to me. At first I was also using dangerouslySetInnerHTML, but the issue seems to be occurring on normal jsx value injection too.
Example here, if you modify the value of const ModifyBody = true; to false and it works as expected, but with the document.body.innerHTML = it doesn't update.
https://codepen.io/eibwen/pen/gjBxrZ
Just to restate it, its a third party library doing the body.innerHTML. Specifically its a library to create a medium.com-like popup when selecting text, if you happened to know a library that could do this with better compatibility with TypeScript/React I'd be all ears on that too
Related
I am trying to hide an element 'GorillaSurfIn' after I click on it.
But also it should fire the 'setShouldGorillaSurfOut' to 'true'. The second part works, but after I added this function:
function hideGorillaSurfIn() {
let element = document.getElementById('gorilla-surf-in');
ReactDOM.findDOMNode(element).style.display =
this.state.isClicked ? 'grid' : 'none';
}
After I click, the code falls apart.
Once I click, the element should be hidden/removed till the next time the App restarts.
Here is the Code Sandbox Link for further explanation.
I am open to any solutions, but also explanations please, as I am still fresh in learning React.
I have changed your code a bit to make it work. You can make further changes according to your need. A few things that I would like to add: -
You should avoid using findDOMNode (in most cases refs can solve your problem) as there are certain drawbacks associated with findDOMNode, such as the react's documentation states "findDOMNode cannot be used with functional components".
I've used refs (forward ref in this case) to make it work.
GorillaSurfIn was called twice, so there were two Gorilla gifs on the screen with same IDs. Not sure if that was the intended behaviour but each element should have unique ID.
Check out the code sandbox.
I am new to React and recently I found out there is the tool called storybook which basically helps to test our React components in isolated manner. However, I also found out that storybook is used when we test our React application, that is, there happens the comparison of snapshots. The question is what is the reason for testing the difference of snapshots? I mean, is it like we create a certain component and create a snapshot for it to ensure that other developers do not change that component accidentally, that is, snapshot in storybook helps us ensure there is no accidental change of components that we created. Is it true?
You create snapshot tests to ensure that your Components renders correctly given a certain input.
This is a way to make sure your code still behaves the way it was intended to. It's to ensure you don't accidentally break something in your code base, but also to alert you when anything changes.
An example:
Say I have a component called ProfileLink that generates a link to a user account:
function ProfileLink(props) {
return <a href ={get_url(user.id)}>{props.user.profileName}</a>;
}
and somewhere else I have a function called get_url:
function get_url(id) {
return "www.example.com/user/" + id;
}
Now, to ensure that my ProfileLink is always working, I can create snapshot, and everytime my tests run, the snapshot will be compared to the current rendered component.
Say someone were to change the get_url function, they might not be aware that it's used in ProfileLink, but as soon as the tests are run, you'll know that something has changed in the ProfileLink component as well.
CodeSandbox with Unit Tests
The CodeSandbox above contains a small code segment that shows the problem. The rendered table contains a bit of data. Everything on the left side is rendered and around the center, #testing-library/react stops rendering anything.
Visually, everything is fine. But the HTML rendered by #testing-library/react misses the entire right half of the table.
You can even see this if you hard reload the tab with CodeSandbox in it, then navigate to the "Browser" tab. The right half will be missing. Click the Browser refresh button in CodeSandbox and everything will be rendered just fine.
Without VirtualTable, everything renders perfectly. However, I need VirtualTable for performance reasons.
Extending the viewport programmatically doesn't help.
// setupTests.js
global.resizeWindow = (x, y) => {
window.innerWidth = x
window.innerHeight = y
window.dispatchEvent(new Event('resize'))
}
// In the test
global.resizeWindow(4096, 2160)
// Same result, no change
Is there any way to keep the benefits of VirtualTable while still running tests on the data contained on the right side of the table?
Here's the response from DevExpress:
Hi,
Thank you for your sample. I have discussed this behavior with our
developers and we concluded that this is the expected behavior. The
VirtualTable plugin renders only visual parts of the Grid control. So,
we recommend that you use the Table plugin for tests and the
VirtualTable plugin in a real application.
Thanks, Alessandro
So it would appear that since we don't have a real browser, the VirtualTable sees no need to render anything.
The solution would be to render a regular Table in a testing scenario, and a VirtualTable in a real-world scenario.
function areWeTestingWithJest() {
return process.env.JEST_WORKER_ID !== undefined;
}
However, using testing code in production code is usually considered bad practice, so I'll just avoid testing VirtualTables and test the data in other places instead.
I have a input field:
<input value="0">
which i can easily clear() and type("123") in cypress.
the value gets updated and everything is fine.
on the other side, a prefilled input field like below I cant update because cypress writes my value of .type("123") just at the beginning of the value.
<input value="1500000">
my method is the following:
.find("input")
.clear()
.type(`${input}{enter}`)
changes on the fields fire redux actions, we use redux for our whole state handling. could that be a problem?
otherwise, do you know of this issue?
Try adding an assertion to make Cypress 'wait' for the input to clear:
.clear().should('have.value', '')
.type(...)
I tested using the HTML found here and everything works fine (in the screenshot I wrote "Stefano" instead of the default value)
You hit the point when you cite React: this kind of state changes requires a bit more work to run as expected because React (and Vue etc.) obviously overwrites everything in the DOM.
You're facing a common issue where React re-renders the component as soon as an event is triggered... so you have to change the input value/defaultValue management in your React component, Google for it and you find a plethora of solutions about that 😊
I've added React, React-DOM, and React Addons library to my pen.
Here's my pen:
https://codepen.io/graven_whismas/pen/QBQQmj
On clicking the button, the word in state should appear, from initial opacity of 0.4 to 1.
But as I click the button, all the content on the page disappears.
This is the error I get:
https://reactjs.org/docs/error-decoder.html?invariant=254&args[]=.0
There's a few things wrong with the code in your pen that will bring about the problem you are having.
The first step is to use the development versions of the libraries, in order to get better error messages. Use https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-with-addons.js instead of https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-with-addons.min.js.
Second, loading several versions of React can cause the issue your are having. Remove https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.production.min.js from the list of external scripts you are loading.
Thirdly, there is a typo when you specify the leave timeout of the animation. You have written transtionLeaveTimeout, where it should be transitionLeaveTimeout. With this type, the transition library will complain about a missing property.
This CodePen summarizes the changes you need to make.