Is this only possible with external URLs and not local? - reactjs

I'm trying to make a photo gallery using react-images, the URLs are correct but the photos themselves are not loading into my web app. I get the broken image icon when switching themodalIsOpen:false to true.
Ive tried looking up examples of the same problems and alternatives, like if the component was configured right or if I am extending it right in the class.
import React, { Component } from 'react';
import Carousel, { Modal, ModalGateway } from 'react-images';
import blksmith from '../images/gallery/illustration/Blacksmith.jpg';
import mage from '../images/gallery/illustration/Mage.jpg';
const images =
[
{
src:{blksmith}
} ,
{
src:{mage}
}
];
class illuGallery extends Component {
state = { modalIsOpen: false }
toggleModal = () => {
this.setState(state => ({ modalIsOpen: !state.modalIsOpen }));
}
render() {
const { modalIsOpen } = this.state;
return (
<ModalGateway>
{modalIsOpen ? (
<Modal onClose={this.toggleModal}>
<Carousel
views={images}
/>
</Modal>
) : null}
</ModalGateway>
);
}
}
export default illuGallery;
This is in the actual gallery.js file, the web page that renders the gallery.
import React from 'react';
import Layout from "../components/layout";
import IlluPhotos from "../components/illustrationGallery";
import SEO from "../components/seo";
import './gallery.scss';
const GalleryPage = () => {
return (
<Layout>
<div style={{width:'100%',height:'250px'}}>
<SEO title="Gallery" />
<IlluPhotos/>
</div>
</Layout>
)
}
export default GalleryPage;
I am seeking some feedback on how to get this to work and what I did wrong, or what I should explore more.

So I ended up adding the pictures I wanted for the gallery to the public folder as mentioned farther down in this post
Since the https://localhost:8000 was appearing in front of the links to the images I wanted to use.
Thank you all for helping me find the answer!!

You don't need to import images.
According to react-images documentation, you just need to pass path to image as a string to <Carousel> component, like in this example below:
import React from 'react';
import Carousel from 'react-images';
const images = [{ src: 'path/to/image-1.jpg' }, { src: 'path/to/image-2.jpg' }];
class Component extends React.Component {
render() {
return <Carousel views={images} />;
}
}

Related

Inserting Middleware(insights) with Instantsearch react

So, we have a functional search with Algolia/Instantsearch/React/Nextjs. But the Insights middleware is currently not setup.
Below is a trimmed version of the implementation, we use custom widgets to have more fine control over the display of results.
We use the hooks implementation for the custom widgets like so
const { hits, sendEvent, ... } = useInfiniteHits(props)
import { useState } from 'react'
import algoliasearch from 'algoliasearch/lite'
import { InstantSearch, InstantSearchSSRProvider } from 'react-instantsearch-hooks-web'
import SearchBox from '#components/swatches/algolia/SearchBox'
import Hits from '#components/swatches/algolia/Hits'
import RefinementList from '#components/swatches/algolia/RefinementList'
import CurrentRefinements from '#components/swatches/algolia/CurrentRefinements'
import { getServerState } from 'react-instantsearch-hooks-server'
import Container from 'react-bootstrap/Container'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { history } from 'instantsearch.js/es/lib/routers/index.js'
import styles from '#styles/page.module.scss'
const Page = ({ serverState, url }) => {
const searchClient = algoliasearch(
process.env.NEXT_PUBLIC_ALGOLIA_INDEX_ID,
process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY
)
return (
<div className={styles.wrapper}>
<InstantSearchSSRProvider {...serverState}>
<InstantSearch
searchClient={searchClient}
indexName={process.env.NEXT_PUBLIC_ALGOLIA_INDEX}
routing={{
router: history({
getLocation: () =>
typeof window === 'undefined' ? new URL(url) : window.location,
}),
}}
>
<Container fluid="lg">
<div className="mb-3">
<SearchBox />
</div>
<CurrentRefinements />
<Hits />
</Container>
</InstantSearch>
</InstantSearchSSRProvider>
</div>
)
}
export default Page
export async function getServerSideProps({ req, res, resolvedUrl}) {
const protocol = req.headers.referer?.split('://')[0] || 'https';
const url = `${protocol}://${req.headers.host}${req.url}`;
const serverState = await getServerState(<Page url={url} />);
return {
props: {
serverState,
url,
},
}
}
So my question is, where do we hook up the insights middleware for this specific implementation?
Reading the docs, (https://www.algolia.com/doc/api-reference/widgets/instantsearch/react-hooks/) I'm not really 100% sure where to start. I can't find anywhere in the instantsearch react docs where it references anyway to configure that sort of thing.
Am I better of just firing events at the API directly instead of with InstantSearch?
Thanks
The trick is finding the InstantSearch instance using useInstantSearch:
const instantSearch = useInstantSearch();
instantSearch.use(middleware)
The docs should tell you what to do from there.

Why the data not displayed in nextjs?

I am making a very very simple nextjs application where I am trying to fetch the data from api.
My requirement is I should display the data in layout.js file and this layout.js file is a children in index.js file.
index.js:
import Layout from "./layout";
import React from "react";
class Home extends React.Component {
render() {
return (
<div>
<Layout />
<h4> Main content will be displayed here !! </h4>
</div>
);
}
}
export default Home;
layout.js:
import React from "react";
import fetch from "isomorphic-unfetch";
function Layout(props) {
return (
<div>
<p>Preact has {props.stars} ⭐</p>
<p> Why I couldn't get the above "props.star" ? </p>
</div>
);
}
Layout.getInitialProps = async () => {
console.log("comes into layout getinitial props");
const res = await fetch("https://api.github.com/repos/developit/preact");
const json = await res.json(); // better use it inside try .. catch
return { stars: json.stargazers_count };
};
export default Layout;
So as per the above given code, I have called the layout page inside index.js page (in my real application I need to call like this only so no changes in calling layout inside index)..
But when I made a console.log() in the function Layout.getInitialProps in layout, it doesn't print anything and hence the api data not fetched..
Complete working demo here with code
Why can't I fetch the data inside the layout.js while calling as a children from index.js?
Also provide me the right updated solution to achieve this.. I really searched for many questions but none solved my issue and I couldn't understand those solutions clearly so please help me with the above given example.
That because getInitialProps can only be added to the default component exported by a page, adding it to any other component won't work.
You should use componentDidMount() or useEffect instead, or move getInitialProps in the index and then pass the result to the component. something like (not tested) :
index.js :
import Layout from "./layout";
import React from "react";
class Home extends React.Component {
render() {
return (
<div>
<Layout />
<h4> Main content will be displayed here !! </h4>
</div>
);
}
}
export default Home;
layout.js
import React from "react";
import fetch from "isomorphic-unfetch";
class Layout extends React.Component {
constructor(props) {
super(props);
this.state = {
stars: false
};
}
async componentDidMount() {
console.log("comes into layout getinitial props");
const res = await fetch("https://api.github.com/repos/developit/preact");
const json = await res.json(); // better use it inside try .. catch
this.setState({ stars: json.stargazers_count });
}
render() {
const { stars } = this.state;
return (
<div>
<p>Preact has {stars} ⭐</p>
<p> Why I couldn't get the above "props.star" ? </p>
</div>
);
}
}
export default Layout;
Edit:
Example with class component
Bonus: If you want to add the layout for all the pages of your app this isn't the best approach, instead you should take a look to custom _app.js, example

Code Mirror will not function in my React application

I am attempting to create a Web IDE sort of like Eclipse Orion. The code editor that I plan to use is Code Mirror; the only difficulty is that I cannot get the code editor to load. Here is the error that I am encountering.
Here is the code that got me to this issue.
import React, { Component } from 'react';
import codemirror from 'codemirror';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/monokai.css';
class Editor extends Component {
componentDidMount = () => {
this.codeMirror = codemirror.fromTextArea(this.codeEditor, {
mode: 'markdown'
});
};
codeEditor = React.createRef();
render = () => (
<div>
<textarea ref={this.codeEditor} />
</div>
);
}
export default Editor;
This issue has been stated many times here, but with no solution that made sense in my situation. Thanks in advance.
This code seemed to do the trick, it was just an issue with the ref.
import React, { Component } from 'react';
import codemirror from 'codemirror';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/lib/codemirror.css';
class Editor extends Component {
componentDidMount = () => {
this.codeMirror = codemirror(this.editor, {
mode: 'markdown'
});
};
ref = React.createRef();
render = () => (
<div>
<div ref={self => this.editor = self} />
</div>
);
}
export default Editor;

Create a first visit popup in react application?

How do I make a first visit popup for my react application? Is it possible to implement using the react-popup module? I used this module below but it does not seem to work. Can you check and let me know what wrong here.
Below is my homepage:
import React, {Component} from 'react';
import './HomePage.css';
import Carousel from 'nuka-carousel';
import HeaderComponent from '../../components/Header/Header.js';
import {Decorators} from './decorators.js';
import Popup from 'react-popup'
export default class HomePage extends Component {
redirectPage = () => {
window.location = '#/dashboard';
}
componentWillMount(){
Popup.alert('my component')
}
render() {
var mixins = [Carousel.ControllerMixin];
return (
<div>
<div className='explore-button-container'>
<button id='exploreBtn' onClick={this.redirectPage}>Explore</button>
</div>
<HeaderComponent id='header' location={this.props.location}/>
<Carousel
autoplay={true}
autoplayInterval={3000}
wrapAround={true}>
//Carousel Content
</Carousel>
</div>
);
}
}
In componentDidMount you cann Access the localstorage and the sessionStorage, where you can set a flag, if this is the first visit.
something like this:
class myComponent(){
constructor(){//do stuff here}
componentDidMount(){
let visited = localStorage["alreadyVisited"];
if(visited) {
this.setState({ viewPopup: false })
//do not view Popup
} else {
//this is the first time
localStorage["alreadyVisited"] = true;
this.setState({ viewPopup: true});
}
render() {
return(<Modal
aria-labelledby='modal-label'
autoFocus={false}
style={modalStyle}
backdropStyle={backdropStyle}
show={this.state.viewPopup}
onHide={this.close}>
<div style={dialogStyle()} >
I'm the Popup Text
</div>
</Modal>);
}
}
This is how i solved it with Modal, but I'm sure you can do it with Popup, too. If you want to view the Popup on every first visit of a session you can use the sessionStorage instead of the localstorage.
Keep in mind that you have to set the styles. You can see an example here: https://react-bootstrap.github.io/react-overlays/
Put some indicator in the Setting, e.g. AsyncStorage, then check if it is the 1st time running the app:
try {
const value = await AsyncStorage.getItem('#isAppFirstTimeRunning');
if (value !== 'true'){
// not first time running
ShowThePopUp();
}
else {
AsyncStorage.setItem('#isAppFirstTimeRunning', 'true');
}
} catch (error) {
// Error retrieving data
}
Yea, you can add pop-up as soon as you logged-in or landed-in your page.
In your component, add the following snippets
import React, {Component} from 'react';
import './HomePage.css';
import Carousel from 'nuka-carousel';
import HeaderComponent from '../../components/Header/Header.js';
import {Decorators} from './decorators.js';
import Popup from 'react-popup'
class HomePage extends Component {
redirectPage = () => {
window.location = '#/dashboard';
}
componentWillMount(){
Popup.alert('my component')
}
render() {
var mixins = [Carousel.ControllerMixin];
return (
<div>
<div className='explore-button-container'>
<button id='exploreBtn' onClick={this.redirectPage}>Explore</button>
</div>
<HeaderComponent id='header' location={this.props.location}/>
<Carousel
autoplay={true}
autoplayInterval={3000}
wrapAround={true}>
//Carousel Content
</Carousel>
</div>
);
}
}
}
componentWillMount() is a lifecycle hook, which will execute the set of statements before rendering your concern components.
And, go through all lifecycle components available for react.

Trouble loading an objects src in ReactJS

I am still a bit new to React and posting on this forum so please bear with me. I currently have two React files which I believe are talking to each other, but there seems to be a disconnect when trying to pull information from an object. One of my React files is:
import React, { Component } from 'react';
import './App.css';
export class App extends React.Component {
render() {
const src = this.props.src;
const alt = this.props.alt;
const width = this.props.width;
const height = this.props.height;
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Will''s weird online shop thing I have no idea about</h1>
</header>
<p className="App-intro">
Click the arrows to browse through the different items.
</p>
<img src={src} alt={alt} width={width} height={height} />
</div>
);
}
}
export default App;
and the other is :
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {App} from './App';
import registerServiceWorker from './registerServiceWorker';
import dogbag from './images/dogbag.jpg';
const DogBagObj = {
src: dogbag,
alt: 'Cute dog handbag',
height: '100px',
width: '70px'
};
const Items = [
DogBagObj,
'https://i.pinimg.com/736x/0b/f4/bd/0bf4bd031a363fc68b56afe6289f450f--random-pokemon-pokemon-stuff.jpg',
'https://pbs.twimg.com/profile_images/881211588748988416/zQL9OLuc_400x400.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Sun-crypto-accelerator-1000.jpg/1200px-Sun-crypto-accelerator-1000.jpg'
]
class OnlineStore extends React.Component {
constructor(props) {
super(props);
this.state = { currentItem: 0 };
this.interval = null;
this.changeItem = this.changeItem.bind(this);
}
changeItem() {
let current = this.state.currentItem;
let next = ++current % Items.length;
this.setState({ currentItem: next });
}
componentDidMount() {
this.interval = setInterval(this.changeItem, 1000);
}
render() {
const src = Items[this.state.currentItem];
return <App src={src} />;
}
}
ReactDOM.render(
<OnlineStore />,
document.getElementById('root'));
registerServiceWorker();
I am confident that I have correctly imported the dogbag.jpg from the image folder and the three images which have direct links to them load correctly.
I feel like my problem lies within getting the DogBagObj.src to correctly read. If I change DogBagObj in the Items array to dogbag it will load the image but I would also like the ability to control multiple tags for each image (such as the alt, height and width). Is there some minor syntax error I am over looking or is this a problem which would be much harder to remedy? Thank you for your time.
Your items array contains multiple data structure but you treat it as if it contains only one.
Either use strings only or objects only.
For example..
Strings only:
const Items = [
DogBagObj.src,
'https://i.pinimg.com/736x/0b/f4/bd/0bf4bd031a363fc68b56afe6289f450f--random-pokemon-pokemon-stuff.jpg',
'https://pbs.twimg.com/profile_images/881211588748988416/zQL9OLuc_400x400.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Sun-crypto-accelerator-1000.jpg/1200px-Sun-crypto-accelerator-1000.jpg'
]
Or use objects with similar data structure:
const Items = [
DogBagObj,
{src:'https://i.pinimg.com/736x/0b/f4/bd/0bf4bd031a363fc68b56afe6289f450f--random-pokemon-pokemon-stuff.jpg'},
{src:'https://pbs.twimg.com/profile_images/881211588748988416/zQL9OLuc_400x400.jpg'},
{src:'https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Sun-crypto-accelerator-1000.jpg/1200px-Sun-crypto-accelerator-1000.jpg'}
]
And in your render method:
render() {
const src = Items[this.state.currentItem].src;
return <App src={src} />;
}

Resources