Call react component function from javascript - javascript

I have one question because I'm not sure if that possible. I have ReactJS project that included some javascript functions.
I found solution to call javascript function from react components with window object but is it possible to call function from reactcomponents in javascript script?
For example I have definied function in React component. Is it possible to call that function in javascript?
Thank you.

A function that is supposed to be used outside React application bundle should be exposed to global scope:
window.foo = () => { /* ... */ };
Then it can be accessed as such:
<script src="react-app-bundle.js"></script>
<script>
foo();
</script>
In case React application bundle is published as UMD module, it can export a function in entry point:
export const foo = () => { /* ... */ };
its namespace will be exposed to global scope when it's loaded via <script>:
<script src="react-app-bundle.js"></script>
<script>
ReactAppNamespace.foo();
</script>
This is the case for a lot of third-party React libraries, React itself exposes React global.
It's preferable to put all code that depends on React application internals to the application itself, so accessing globals is not needed.

Related

create my own global variable in nuxt.js (with vuetify)

I'm developing an app with nuxt and I'm tired of having to write an if statement in pages using this.$Vuetify.breakpoint.name == 'xs' for responsiveness every time. So I would like to create my own variable and call this long variable.here is my code↓
(mynuxtapp/plugins/createCustomVar.js)
import Vue from "vue";
Vue.prototype.$bp = Vue.prototype.$vuetify.breakpoint.name;
console.log(Vue.prototype.$bp);
I have already set nuxtconfig to run the plugin.
But it returns an error:
TypeError: Cannot read property'breakpoint' of undefined.
Apparently I can't access vuetify using "$", even though I can do it in pages.
What should I do? and Are there any easier ways or best practices?
Thank you for reading the question at the end!
The $vuetify property exists on the Nuxt context, not the Vue prototype.
Each module under plugins/ should return a function that receives the Nuxt context as the first argument. That context contains the $vuetify object setup by the #nuxtjs/vuetify plugin.
The second argument of the Plugin API is inject, which allows you to inject globals into the Nuxt context.
So your plugin should look similar to this:
// ~/plugins/myGlobals.js
export default ({ $vuetify }, inject) => {
// inject makes `$bp` available in context (the `$` prefix is automatically prefixed)
inject('bp', $vuetify.breakpoint.name)
}
demo
How about to start with you simply log out the context object and see what you have. I think you'll probably find that the Vuetify object is lying somewhere else.
export default (context, inject) => {
console.log('context:', context)
}
Docs for setting plugins can be found here

sveltejs - static properties on components

I have a scenario where I need to provide information to a component class such that downstream instantiations can make use of that info.
For instance:
import { AComponent } from 'AComponent.svelte'
...
AComponent.classInfo = {something: somedata}
And then, the component could access that information as in:
<script>
let something = AComponent.classInfo.something
</script>
There seemed to be some effort in providing this kind of functionality in V2 (I'm using 3) that was discussed in these issues: Support Component Static Method #480, which resulted in Added setup function which can supply static methods/properties. #572.
However, scanning the current docs reveals no such setup method. So, did this survive from V2 to 3 & if not, is there some way to do this?
You can define static properties that are not instance specific in the module script block
<script context="module">
export const someValue = 123
</script>
<script>
// Normal component stuff
</script>
and then import it directly from the component file:
import { someValue } from './MyComponent.svelte'
Note that this is a value shared among all instances of this component.
At least in version v3.32, it's not possible to define static properties in a Svelte Component. Only named exports are possible.
The only workaround I known is using a custom webpack loader/rollup plugin, and the implementation is never pretty.

Use custom JavaScript code in a Vue.js app

I'm trying to insert JavaScript code in a Vue.js router app. I need to load data from the CMS the app is served from. In order to get the data from the CMS I have to use a JavaScript library from the CMS which is not made for Vue and is not exporting it's class/functions like modern JS. So I import the JS library from in the index.html by a script tag. This works as intended.
But now I have to use the class from this CMS JavaScript library.
Before writing this as a Vue-Router app I just have used Vue for templating purposes.
So I had some code packed in the window.onload event handler.
I have to create an instance for the CMS data access class.
But this leads to a build error (using vue-cli build). Since there
are no understandable error messages from the build process
I have to use trial and error. Even simple variable assignments like var a = 1 seem not to be allowed.
A console.log('something') works. But nothing else seemes to be allowed (except defining the onload-event handler)
I have added this code in a <script> Tag inside App.vue (which was created by vue-cli create)
window.onload = function() {
try {
// Instantiate class obj for CMS data access
cmsDataAccessObj = new CMSAccessData();
waitForPlayerData = true;
}
catch (e) {
console.error(e);
}
}
UPDATE
After testing the different solutions from the answers I got aware that using non-instance variables seems to cause the build errors.
This gives an error:
waitForPlayerData = true;
This works:
this.waitForPlayerData = true;
I wouldn't recommend using window.load to run your code. There are more native approaches to do this in Vue.js.
What you should do in the case you want to run it in the main component of the app before it's been loaded is to put the code inside the beforeCreate lifecycle hook of the main component.
...
beforeCreate () {
this.cmsDataLoader()
},
methods: {
cmsDataLoader () {
try {
// Instantiate class obj for CMS data access
cmsDataAccessObj = new CMSAccessData();
waitForPlayerData = true;
}
catch (e) {
console.error(e);
}
}
}
...
This will run the code everytime a component is created before the creation. You could also use the created lifecycle hook if you want to run it after the creation of the component.
Check the following link for more information about lifecycle hooks.
The best way to place JavaScript in Vue.js App is mounted function, it is called when the component is loaded:
export default {
name: "component_name",
mounted() {
let array = document.querySelectorAll('.list_item');
},
}
You don't need window.onload, you can just put whatever you want there. I'm not entirely certain when precisely in the lifecycle it renders and maybe someone can hop in and let us know but it for sure renders when page starts. (though it makes sense that it does before the lifecycle hooks even start and that it'll solve your needs)
Better & easier solution if you want to load it before Vue loads is to add it to the main.js file. You have full control there and you can load it before Vue initializes.
No need for window.onload there either, just put it before or import a JS file before you initialize Vue, because it's going to be initialized by order.

Are variables defined outside of a react component considered global?

I know that using global variables are a bad practice. I also know in javascript variables defined outside of a function are considered global. Is this also true for variables defined outside of a react component, be it a functional component or a class. It appears as no because some css in js libraries use syntax like this but I don't understand why it wouldn't be a global. For example:
import ...
const styles = ...
const MyComponent = () => {
...
}
export default MyComponent
Is styles a global variable here? Why or why not?
In React, as in many modern Javascript frameworks, they use script modules, which sandbox each script. This means that you cannot define a global unless you specifically assign something to the window object.
const local = {};
window.global = {};
A script module is defined by setting a script tag's type to be module:
<script type="module" src="myscript.js"></script>
You should see the resulting HTML that react creates contains these script types.

Call external Javascript function from react components

Im not sure if this has been asked before or anybody has encountered the same issue on reactjs. So the scenario is like this, I have an index.html file that includes some javascript. Now on my react component, I have a condition that will render only if the condition is true. This means that initially when my page loaded the component has not been rendered yet. When I toggle a button this is where that component gets rendered. That child component needs to call a javascript method that was included on my index.html. How should I do this?
Any help is greatly appreciated.
In index.html
<script type="text/javascript">
function test(){
alert('Function from index.html');
}
</script>
In your component
componentWillMount() {
window.test();
}
2022 Typescript edit:
Create a file global.d.ts like so (doc):
interface Window {
test: () => void;
}
✔
Try this solution to call global functions from React with TypeScript enabled:
Either in index.html or some_site.js
function pass_function(){
alert('42');
}
Then, from your react component:
window["pass_function"]();
And, of course, you can pass a parameter:
//react
window["passp"]("react ts");
//js
function passp(someval) {
alert(`passes parameter: ${someval}`);
}
So either you define the method on global scope (aka window).
And then you can use it from any methods, being React or not.
Or you can switch to module based paradigm and use require/import to get the module and use the function.
For bigger projects the latter is better as it's scales, while if you need a demo or POC you can certainly hook all to global scope and it will work.
More information about modules is at: http://exploringjs.com/es6/ch_modules.html
You can attached your method to the global window object and than use it like that in your component:
<button onClick={this.howItWorks} type="button" className='btn'>How it Works</button>
howItWorks = () => {
window.HowItWorksVideo();
}
for typescript users, try this:
declare global {
interface Window {
externalMethod: (params: any) => void;
}
}
then you would be able to call it like this in your react component
window.externalMethod(params)

Categories

Resources