I have 4 react components header,modal,container,index. In index.js I'm rendering all the components. Now, I have one problem My HTMl page is using one js file(home.js). It is executing the before the DOM loads. So, it is not getting any properties of the DOM so it is failing. So, How I can the execute that js file once the DOM is loaded?
Wrap your home.js code with a global function and call to that function in componentDidMount life cycle method of your root React component.
So your home.js file will look something like this.
window.executeHome = function() {
// your curren home.js code goes here
}
and inside the componentDidMount method of your root React component, you can call above method to make sure that you are running home.js code after loading the React components.
componentDidMount() {
window.executeHome();
}
However, consider this as a workaround and it's usually not something recommended. The better approach would be writing your home.js code also inside a React component.
please try
componentDidMount() {
}
componentDidMount() automatically called after render() method.
Related
I'm rendering a react component like this
export class MyClass {
render(state) {
ReactDOM.render(<Dashboard {...state} />, document.getElementById("root"));
}
}
The render function is called externally by the environment my class is injected in. Although this works fine, the problem is that the environment can call that render method again with an other state object. How can I pass that data to that rendered Dashboard component?
I tried to run ReactDOM.render again, but then nothing happens. The only solution I found was to remove that root element, insert it again and then run ReactDOM.render again, but that doesn't really sound like a solid solution to this trivial problem. Any suggestions how to do this?
I want to create a build of my javascript application using react which currently is just a single file defined as below. It does nothing but creates a div and keeps on changing the color of the hello-world text after it mounts.
import * as React from "react";
import * as ReactDOM from "react-dom";
class App extends React.Component {
componentDidMount() {
const colorBox = ["red","blue","green"];
const element = document.getElementById("my-div");
setInterval(() => {
element.style.color = colorBox[parseInt(Math.floor(Math.random() * colorBox.length))];
}, 3000);
}
render() {
return (
<div id={"my-div"}>
Hello, World.
</div>
);
}
}
ReactDOM.render(<App />,
document.body.appendChild(document.createElement("div")));
I am using parcel js as a bundler. I bundle my javascript as parcel build index.js and this creates a build of my javascript file inside dist folder. So far, so good. But the moment, I load this javascript using a script tag on my website as:
<script type="text/javascript" src="https://mycdn.com/bundle.index.js"></script>
It throws an error
index.js:16 Uncaught TypeError: Cannot read property 'appendChild' of null
at Object.parcelRequire.Focm.react (index.js:16)
at f (index.js:1)
at parcelRequire.YOwE (index.js:1)
at index.js:1
Why it cannot access appendChild of document.body? I also checked that document.body is null. What is happening here? What is it that I am missing?
First of all I'm not sure this is a great idea to have code in the bundle that directly affects the page like this.
My guess as to why this is happening is it has to do with when the bundle is loaded in the page. Is it in head? If so document.body may not be available.
It is probably best if you are going to do something like this to use the events associated with the document being ready.
This can get complicated depending on your needs, but if you have access to jQuery, you can use .ready().
If not you can use various vanilla js options.
I guess your problem is related to the bundle or you ask for an element before it is available because it is working fine here: https://jsfiddle.net/rL6dnhps
If you load it from the head, try to put at the end of the body in order to wait for the body to be ready or wrap it inside an IIFE like below:
(function() {
// the DOM will be available here
ReactDOM.render(<App />,
document.body.appendChild(document.createElement("div")));
})();
Need to import "validation.js" file within another javascript file in reactjs once the main file render method is completes it execution
import './Validations';
should render this JS file once the main component's render method complete its execution
What you're trying to achieve is not really the way react likes to behave and probably is a mistake. if you need some extra functionality to be available in your component you could define a class, put your external logic in there and then instantiate an object from that class in your component's constructor or render method, and use whatever functionality you need in from there.
You can use react-loadable library to lazy load javascript file.
import Loadable from 'react-loadable';
const LoadableTest = Loadable({
loader: () => import('./validations.js'),
loading() { // you could write your spinner while the file is being loaded.
return <div>Loading...</div>
}
});
class MyComponent extends React.Component {
render() {
return <LoadableTest/>;
}
}
Im relatively new to React (i'm using preact.js, to be precise) and i am trying to code split out react components using webpack 2.
Im exporting my component as stated in the documentation and i am then importing it on load.
import('./components/List').then((List) => {
render(<List />, document.getElementById('main'));
});
The script loads but i'm not handling the promise callback correctly and finding it hard to see any documentation that shows a working version.
List returns the following object:
I saw your repo. It looks like that your list component doesn't have a export default.
I would add the default and inside your then, when you handle the promise, I'd do it in this way
.then(module => {
const Component = module.default;
render(<Component />, document.getElementById('main'))
})
Trying to instantiate mdl into a vuejs project (vue v2.1). Running into a very similar issue to this, except when I call mounted () { componentHandler.upgradeDom()} in my App.vue, it's returning:
TypeError: _materialMin2.default.upgradeDom is not a function
Furthermore, if I type componentHander.upgradeDom() in the browser console it'll do what's expected without error. If I console.log(componentHandler.upgradeDom()) in the mounted hook then it returns an emtpy object. Have tried adding a this.$nextTick handler on mounted as well to no avail.
Am importing the material.js file like so:
import componentHandler from 'material-design-lite/material.min.js'.
Tried to add it as a global as well just by dumping it in a script tag in index.html, and loading it by cdn, nothing seems to work properly.
For easy reading, this is what the whole thing looks like minus irrelevant stuff:
import componentHandler from 'material-design-lite/material.min.js'
export default {
name: 'app',
components: {
...
},
mounted () {
this.$nextTick(() => {
componentHandler.upgradeDom()
})
}
}
Also when I do it with ready () {..} (old school vue) instead of mounted () {...} it doesn't return the error, but also doesn't update each element correctly.
Found a fix for it based on a similar problem in react: basically did the webpack version of this, changed require to import componentHandler from 'exports?componentHandler!material-design-lite/material', and used the mounted hook same as before.
Still having an issue with code in nextTick not updating all child component elements, but moving all of it to another child component that had most of the buggy elements seems to have worked. Was formerly in App.vue.