How to use react components inside a Gatsby plugin? - javascript

I want to create a Gatsby plugin with an index.js file but I want to render React components inside the plugin. I imported react:
const React = require('react');
const MyComponent = require('myComponent');
modules.exports = () => {
const myRenderedComponent = React.render(MyComponent);
...
}
But it fails because it doesn't understand the import statement I have in myComponent.js.
How can I render a component inside a Gatsby plugin instead of having to write the HTML?
I would be too silly to write the component's HTML by hand instead of just using the component itself

Related

Can't call custom hook from custom hook in react

I have a React app created with create-react-app.
I'm trying to make a custom hook using Microsoft Authentication Library (MSAL). MSAL has a custom React hook that I want to call from my own custom hook.
When I use a hook (any hook) inside my custom hook in a separate file I get this in the browser:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
// ourhook/index.ts
import { useEffect } from "react";
export const useMsal2 = () => {
useEffect(() => {
console.log("Hello from our hook!");
});
};
// app.tsx
import React from "react";
import { useMsal2 } from "./ourhook";
const App = () => {
useMsal2();
return <div>App</div>;
};
export default App;
If I call
const { instance } = useMsal();
directly from App.tsx everything works fine. It only appears to be a problem if my custom hook is in its own file.
From what I see I'm not violating any hook rules. I'm calling a hook that's calling a hook, and the first call is from a top level component.
I have read other threads here about hooks in hooks, but none of them has an answer that fits this problem.
Have I missed something about hook rules, or what might be causing this?
Okay, I forgot that we tried to have /ourhook as a freestanding project and then copy pasted it into a create react app app.
Some of you were right, it did have its own version of react.
I'm just going to hide under a rock for the rest of the week.
Thanks for all your help! <3
Try to add this comment just above:
import { useMsal } from "#azure/msal-react";
export const useMsal2 = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { instance } = useMsal();
const request = "";
return {
loginRedirect: () => console.log(""),
}
};
I don't know what useMsal looks like, but from what I see, you don't actually violate any hook rule.

Convert website from HTML,CSS,bootstrap & JQuery to React?

Hi guys hope you're fine, I'm student and I have this year to do some thing like a project to end my studies , so I chose to create a website (using React/Django) I already have the site but made by HTML,CSS,bootstrap & JQuery , so now i have to convert it to react , but i have a problem i don't know how to include some js files inside a components , every things else is going good, I need just what is in the js files to applied it in some components.
Hope you help me out.
cordially
You can have javascript code inside your components likewise
const Component = props => {
//javascript code
return (<div>-- Component JSX---</div>)
}
if the javascript code if just needed for the initializing of the component you can use react hooks to run a piece of code only one time after the component is created.
import React, { useEffect } from 'react';
const Component = props => {
useEffect(() => {
// javascript code
}, [])
return (<div>--Component JSX---</div>
}
the empty array as second argument indicates the useEffect hook that the effect should only be ran once after the component has been initialized.
So the way React works is you will be building "HTML" using React functional/class components like this example
import React from 'react';
//Just like a normal javascript function, it listens to in this
instance, the return statement. You're returning regular HTML.
function Navbar() {
return (
<div>This is some text built by react</div>
<p>Saying hello to react by building a functional component</p>
)
}
export default Navbar; //This right here is exporting the file so it can be
//used elsewhere just import it in other file.
So the return is where you will build your website, then in the next component you will import should look something like this.
Normally, it is called App.js or in some instances where it's more complex it's anythinng you want.
import Navbar from '../components/Navbar.js';
function App() {
return (
<Navbar /> //Now you don't have to write your main content in here you can
//just import it. Just like Navbar
<div>This is my main content in page</div>
)
}

Dynamic Vue Import from a subfolder

I am trying to import all .vue files in a certain subfolder into another component. I know about Global registration of Base components but this does not seem to help me here.
Let's say I have default Vue component (not the main one) with something like this:
export default {
components: {
red: () => import('./panes/red'),
},
data() {
return {
current: false,
};
},
and my file structure is something like:
/src
- main.js
- main.vue
-- components/
-- panes/
--- /red.vue
--- /green.vue
--- /blue.vue
-- SubMain.vue
I am trying to dynamically create the components object for the SubMain.vue folder.
So I try something like this in SubMain.vue:
import myComponents from './src/components/panes';
...
components: Object.keys(myComponents).reduce((obj, name) => {
return Object.assign(obj, { [name]: () => import(myComponents[name]) })
}, {}),
But eslint is giving me errors about Missing file extension and Unable to resolve path to module on the myComponents variable. Yes, I double checked my path and tried other paths. Nothing. I am using the Vue CLI 3 project.
If you're using Webpack, you can use require.context:
import _kebabCase from lodash/kebabCase
const components = require.context('src/panes', true)
components.keys().map(component => {
// turn './ComponentName.vue' into 'component-name'
const componentName = _kebabCase(
component.replace(/^\.\//, '').replace(/\.vue$/, '')
)
// register new component globally
Vue.component(componentName, components(component))
})
I don't think you can import multiple components that way without an index file that aggregates the component import/exports for you. See Import multiple components in vue using ES6 syntax doesn't work

React Component not created until render method

I am using Styled Components but getting a problem trying to style a component of my own creation.
It is exported in the normal way from a separate npm package.
Package
FormComponents.js
export SubmitButton from './_submit-button';
_submit-button.js
export styled.button`somestyles`;
components.js
import * as Form from './form-components';
export { Form }
index.js
import * as Components from './components'
export const FormComponents = Components.Form;
Then in my actual component I want to use it I have:
import { FormComponents as Form } from 'packagename';
const Button = styled(Form.SubmitButton)...
and I'm receiving the error cannot read SubmitButton of undefined.
If however I put the const Button = ... in the render method, it finds everything fine. So I assume that the component isn't being instantiated until React kicks in.
It's possible with other elements however, for example if I change it to use:
const Button = styled(Link)
(Link from react-router-dom)
it finds it fine.
Am I exporting wrong?

How do I add React as a global whilst running unit tests?

In my Rails project, I am using the react-rails gem, which does the following:
window.React = React;
This is pretty handy, but when I run unit tests using Jest, that global is not there and I get an error from the file containing the component I am testing saying that React is not defined.
If I define React in the component file using
import React from 'react';
Then it causes errors due to loading React twice.
How should I define a global React variable in my unit tests so they work?
In your test file, do:
import React from 'react'
describe('something',() => {
window.React = React
// so when you require() your component, window.React is already set
var MyComponent = require('MyComponent').default
it('does something', () => {
// do something
})
})

Categories

Resources