React js - make button link to a different app - javascript

I want to make a button to link to a different app with react librery.
my code looks like this
import React, { Component } from "react";
import { Link, NavLink, Redirect } from "react-router-dom";
import "./subportfolio.scss";
import Coffee1 from "../../assets/coffee-1.jpg";
import Coffee2 from "../../assets/coffee-2.jpg";
import Coffee3 from "../../assets/coffee-3.jpg";
import Coffee4 from "../../assets/coffee-4.jpg";
import CoffeeShop from "../../assets/coffee-shop-1.jpg";
import Tea1 from "../../assets/tea-1.jpg";
import Tea2 from "../../assets/tea-2.jpg";
import Tea3 from "../../assets/tea-3.jpg";
class SubPortfolio extends Component {
state = {
projectImg: {
project1: Coffee1,
project2: Coffee2,
project3: Coffee3,
project4: Coffee4,
project5: CoffeeShop,
project6: Tea1,
project7: Tea2,
project8: Tea3
},
direct: ""
};
directToGithub = () => {
this.props.history.go("https://github.com");
};
render() {
console.log(this.state.direct);
return (
<div className="subPortfolio">
<div className="subPortfolio__content">
<div className="subPortfolio__content--detail">
<h2>Image Format</h2>
<div className="subPortfolio__content--refer">
<div className="subPortfolio__content--button">
<button
id="github"
type="button"
onClick={this.directToGithub}
>
github
</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default SubPortfolio;
I tried all of the history properties but all of them throw an error
TypeError: Cannot read property 'go' of undefined
SubPortfolio.directToGithub
C:/Users/Ermais Kidane/Documents/REACT/portfolio/src/components/subportfolio/subportfolio.js:30
27 | };
28 |
29 | directToGithub = () => {
> 30 | this.props.history.go("https://github.com");
| ^ 31 | };
32 | render() {
33 | // const projectsImage = Object.keys(this.state.projectImg).map(proImg => {
I tried using Link React-router-dom and to adds to with the previous url like (http://localhost:3000/https://github.com) and does not take make anywhere.
how could I make the link to another web site? thanks for your help.

If you are trying to get directed to an external website, just use the standard <a></a> tag
<button id="github" type="button">github</button>
if you are trying to use the <Link> to get directed to an internal link, it would look more like this
<Link to="/github"><button id="github" type="button">github</button></Link>
And the link would then have to be setup in the app.js using the router to then be directed to the named component

If you want to programmatically direct to an external website, you can also use window.location = "https://github.com" or, assuming a global window object, location = "https://github.com".

Related

StaticImage not showing up in test render in Gatsby

I have been searching through google for this for about an hour and have decided that I will likely need more direct assistance instead of just looking at other people's post.
My goal is to be able to have a jest test using this library https://github.com/testing-library/react-testing-library to be able to use the 'render' function and check that a StaticImage component inside of a custom component is rendered.
Currently this is my NavBar.tsx:
import React from 'react';
import { StaticImage } from 'gatsby-plugin-image';
import Test from '../Test/Test';
const NavBar: React.FC = () => {
return (
<nav data-testid="nav-bar">
<Test siteTitle="TestssS" />
<StaticImage src="../../images/logo.png" alt="Logo" />
</nav>
);
};
export default NavBar;
And this is my NavBar.test.tsx:
import React from 'react';
import { render } from '#testing-library/react';
import NavBar from './NavBar';
describe('Ensuring NavBar is Rendered', () => {
test('Ensuring Navbar is in the page', () => {
const { getByTestId } = render(<NavBar />);
expect(getByTestId('nav-bar')).toBeInTheDocument();
});
});
describe('Squarehook logo is inside navbar', () => {
test('Ensure Logo is in Navbar', async () => {
const { getByAltText } = await render(<NavBar />);
expect(getByAltText('Logo')).toBeInTheDocument;
});
});
The test I am talking about is the 'Ensure Logo is in Navbar' test at the bottom. Ideally, I'd be rendering the NavBar component which would have the StaticImage component. Theoritically once StaticImage has completed rendering there would be an img tag with the alt attribute of 'Logo'.
However once I run npm test I get this result:
TestingLibraryElementError: Unable to find an element with the alt text: Logo
Ignored nodes: comments, <script />, <style />
<body>
<div>
<nav
data-testid="nav-bar"
>
<h1
class="header"
data-testid="test"
>
TestssS
</h1>
</nav>
</div>
</body>
13 | test('Ensure Logo is in Navbar', async () => {
14 | const { getByAltText } = await render(<NavBar />);
> 15 | expect(getByAltText('Logo')).toBeInTheDocument;
| ^
16 | });
17 | });
18 |
at Object.getElementError (node_modules/#testing-library/dom/dist/config.js:38:19)
at node_modules/#testing-library/dom/dist/query-helpers.js:90:38
at node_modules/#testing-library/dom/dist/query-helpers.js:62:17
at getByAltText (node_modules/#testing-library/dom/dist/query-helpers.js:111:19)
at Object.<anonymous> (src/compontents/NavBar/NavBar.test.tsx:15:12)
You can see from the log above that the nav and the Test component get rendered, but for some reason there is no StaticImage/Img element at this point in time. I was reading a resource that said I may have needed to add await to those commands so I tried that on all of them but without any success.
I am using Gastby with Typescript.
the packages that are related to this is the
gatsby-plugin-image and the #testing-library/react.
I appreciate any help in advance!

Cannot read property 'getAttribute' of null on TextArea

I'm just learning some react stuff at the moment and am running into an error when trying to implement https://www.npmjs.com/package/textarea-markdown this.
I think the error comes from the fact that the script is attempting to change the textarea before the textarea is loaded, but I don't know how to fix it.
Any help is much appreciated
Code below
text.js
import React, { Component } from 'react';
import './texts.css';
import TextareaMarkdown from 'textarea-markdown'
let textarea = document.querySelector("textarea");
new TextareaMarkdown(textarea);
function Texts() {
return (
<div >
<h2>Editor</h2>
<textarea id="editor" data-preview="#preview"></textarea>
<h2>Preview</h2>
<div id="preview"></div>
</div>
);
}
export default Texts;
App.js
import logo from './logo.svg';
import './App.css';
import Texts from './components/texts/texts';
function App() {
return (
<div className="App">
<header className="App-header">
<Texts></Texts>
</header>
</div>
);
}
export default App;
The error I receive is this
TypeError: Cannot read property 'getAttribute' of null
TextareaMarkdown.setPreview
node_modules/textarea-markdown/lib/textarea-markdown.js:65
62 | value: function setPreview() {
63 | var _this2 = this;
64 |
> 65 | var selector = this.textarea.getAttribute('data-preview');
| ^ 66 | if (selector) {
67 | Array.from(document.querySelectorAll(selector), function (e) {
68 | return _this2.previews.push(e);
View compiled
You can use you following code inside a useEffect
as like following
import React, { Component, useEffect } from 'react';
import './texts.css';
import TextareaMarkdown from 'textarea-markdown'
function Texts() {
useEffect(()=>{
let textarea = document.querySelector("textarea");
new TextareaMarkdown(textarea);
},[]);
return (
<div >
<h2>Editor</h2>
<textarea id="editor" data-preview="#preview"></textarea>
<h2>Preview</h2>
<div id="preview"></div>
</div>
);
}
export default Texts;

Stuck at "Cannot read property 'props' of undefined"

I'm testing out the gatsby-source-wordpress plugin from Gatsby, and I'm trying to get my menu to fetch the links from my Wordpress site.
I've managed to get all of the Wordpress schemas to come up in GraphiQL, and copied the GQL code from there.
I've made a Layout component, where I've tried most of what I can to make it work. However, I keep getting TypeError: Cannot read property 'props' of undefined when I deploy my Gatsby site to localhost.
Anyone ever come across this before? I'm kinda new to GraphQL and all that, so I honestly have no clue what's wrong, or if it's even GraphQL that's causing this. Any help is greatly appreciated! (Sorry if this is a really simple fix, and I'm just being ignorant)
I've searched through Google, Stack Overflow, Youtube, and anywhere else I could think of.
Code
Layout
import React, { Component } from "react";
import PropTypes from "prop-types";
import { StaticQuery, graphql } from "gatsby";
// import Image from "gatsby"
import Header from "../Header";
import MainMenu from "../Nav";
// import Aside from "../Aside"
// import Footer from "../Footer";
const Layout = ({ children }) => {
const menu = this.props.data.allWordpressWpApiMenusMenusItems;
return (
<StaticQuery
query={graphql`
query menuQuery {
allWordpressWpApiMenusMenusItems {
edges {
node {
id
name
items {
title
object_slug
url
}
}
}
}
}
`}
render={menu => (
<>
<Header>
<MainMenu menu="{data.allWordpressWpApiMenusMenusItems}" />
</Header>
<div className="Layout">
<main>{children}</main>
</div>
<footer>Footer</footer>
</>
)}
/>
);
};
Layout.propTypes = {
children: PropTypes.node.isRequired
};
export default Layout;
Menu component
import React, { Component } from "react";
// import { Link } from "gatsby";
class MainMenu extends Component {
render() {
const data = this.props.data.allWordpressWpApiMenusMenusItems;
console.log(data);
return (
<nav className="main-menu">
<ul>
<p>Test</p>
</ul>
</nav>
);
}
}
export default MainMenu;
Expected result: The site renders on localhost:8000
Error messages I recieve:
src/components/Layout/index.js:11
8 | // import Aside from "../Aside"
9 | // import Footer from "../Footer";
10 |
> 11 | const Layout = ({ children }) => {
12 | const menu = this.props.data.allWordpressWpApiMenusMenusItems;
13 | return (
14 | <StaticQuery
You're accessing this.props in a function based component. Change your declaration to
const Layout = ({ children, data }) => {
const menu = data.allWordpressWpApiMenusMenusItems;
Or explicitly declare props and destructure the properties you want
const Layout = props => {
const { data, children, ...rest } = props
const menu = data.allWordpressWpApiMenusMenusItems;

How to resolve this "Target container is not a DOM element." in React with React-Image Gallery/Lightbox?

Im trying to find a solution to what Ive been experiencing with image based galleries (in example lightbox or FancyBox). This error came up after following this doc and using this code as an
example.
I have tried using react-images to no avail, the modal doesn't display right, so I tried the links react-photo-gallery and I am encountering this error. Ive tried converting it to a component, and it didn't agree with the App function in the top portion of the file. I also tried creating a html file in my pages directory and added the import link to the illustrationGallery file, but that didn't seem to work.
My illustrationGallery file
import React, { useState, useCallback } from "react";
import { render } from "react-dom";
import Gallery from "react-photo-gallery";
import Carousel, { Modal, ModalGateway } from "react-images";
import { illustrations } from "../components/illustrations";
import Artwork from '../pages/gallery';
function App() {
const [currentImage, setCurrentImage] = useState(0);
const [viewerIsOpen, setViewerIsOpen] = useState(false);
const openLightbox = useCallback((event, { photo, index }) => {
setCurrentImage(index);
setViewerIsOpen(true);
}, []);
const closeLightbox = () => {
setCurrentImage(0);
setViewerIsOpen(false);
};
return (
<div>
<Gallery illustrations={illustrations} onClick={openLightbox} />
<ModalGateway>
{viewerIsOpen ? (
<Modal onClose={closeLightbox}>
<Carousel
currentIndex={currentImage}
views={illustrations.map(x => ({
...x,
srcset: x.srcSet,
caption: x.title
}))}
/>
</Modal>
) : null}
</ModalGateway>
</div>
);
}
render(<App />, document.getElementById("illuGallery"));
Local host window error
invariant
node_modules/react-dom/cjs/react-dom.development.js:56
render
node_modules/react-dom/cjs/react-dom.development.js:21195
▲ 2 stack frames were expanded.
Module.<anonymous>
src/components/illustrationGallery.js:43
40 | </div>
41 | );
42 | }
> 43 | render(<App />, document.getElementById("illuGallery"));
44 |
This error description is towards the top, but there are more
Just trying to achieve something that displays a proper image gallery using react, would it be easier to just make it using another doc or from scratch? Does anyone have any recommendations or answers to help?
This happens because:
document.getElementById("illuGallery") can not find an element with id #illuGaller.
if you are willing to make it work, and this is the only component you actually want react to render.
as from the example of the codesandbox project.
You go to your template, where react renders the ellement. basically index.html or template.html, in the example it's index.html
And make sure that the root element there which where react will inject your JSX, make sure it has the id illuGallery

Import JavaScript after HTML is rendered in REACT

In order to study the react framework, I've been developing a simple web application to rate books. It's currently looking like this:
And the idea of the side bar is simple enought: it's width will be 0 when hidden, and when I click a open menu button it will be set to another width.
The code behind it all is looking like this:
import React from 'react';
import { Link } from 'react-router-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import home from '../../image/side-nav/home.png';
import list from '../../image/side-nav/list.png';
import '../../css/SideNavBar.css'
import * as utils from '../../scripts/utils.js';
const SideNavBar = () =>{
return(
<Router>
<div>
<span className="spanOpen" onClick={utils.openNav()}>☰</span>
<div className="sidenav">
<a className='closebtn' onClick={utils.closeNav()}>×</a>
<ul>
<li>
<Link to='/'><img src={home} alt='Home' /><span className='h-item'>Home</span></Link>
</li>
<li>
<Link to='/books'><img src={list} alt='Books' /><span className='b-item'>Books</span></Link>
</li>
</ul>
<div className='sidenav-footer'>
<hr />
<small>Pelicer © 2018</small>
</div>
</div>
</div>
</Router>
);
}
export default SideNavBar;
And here is the code of the util.js file, which contains the the fucntions to change:
export function openNav() {
// document.getElementsByClassName("sidenav")[0].style.width = "315px";
}
export function closeNav() {
// document.getElementsByClassName("sidenav")[0].style.width = "0";
}
But when I run it, I get the error: TypeError: Cannot read property 'style' of undefined. It happens because it is trying to change the width of somethings that has not yet been created. What I want to do, and tried using componentDidMount, is to import the JavaScript after the HTML has been rendered, in a way that when it sets the width, the component is already there. Can someone help out in a solution?
You're calling the utils.xyz functions too soon. This:
<span className="spanOpen" onClick={utils.openNav()}>☰</span>
calls utils.openNav and uses its return value as the value of the onClick. You probably meant:
<span className="spanOpen" onClick={utils.openNav}>☰</span>
(without the ()) to just refer to the function. That will work if utils.openNav doesn't need this to refer to utils during the call. If it does need this to be utils during the call:
<span className="spanOpen" onClick={() => utils.openNav()}>☰</span>
...which defines a function and uses that function as the value of onClick.
In that case where this matters, probably better to change that functional component to a class component, create that function once, and reuse it:
class SideNavBar extends React.Component {
constructor() {
this.openNav = () => utils.openNav();
// ...
}
// ...
}
and then in render:
<span className="spanOpen" onClick={openNav}>☰</span>

Categories

Resources