(reactjs) Include local Images in react component - javascript

I have the following component, which renders an image using html img src=".."
export default class Landing extends Component{
render() {
return(
<div className="topimg">
<img src={'test.jpg'}/>
</div>
But the Page does not display the image. The folder structure is the following
/layout/Landing.jsx
/layour/test.jpg
It works for web urls but not for local files.

Not sure how you are building your app but you could attach your images to the component by requireing them first. That way the app knows to include the image (referenced relatively from the component) before rendering.
export default class Landing extends Component {
constructor( props ) {
super(props);
this.images = {
test: require('./test.jpg')
};
}
render() {
return (
<div className="topimg">
<img src={this.images.test}/>
</div>
);
}
}

Related

What is the best way to use external JSON file data as a props for landing-section in different pages?

I am new to reactJS and I need an answer for this confusing problem.
I have a landing page that I want to use in my home and contact page. What I want is to send external JSON info as props to these pages and every time I create new page.
I have an external JSON file and I want to add it as a props to my landing page file
What is the best practice to do so, should I save within a state and send it as a props or send it directly as a props
JSON File:
{
"landing page" : {
"home": {
"id":1,
"image": "../media/video/Ai Motion5.mp4",
"title" : "MyAkbar for IT consultant & Services",
"description":"Boost up Your Works With our Services. My Incrediable Team is Here to Save Your Time and Money.",
"buttonOne": "Get A Demo"
},
"Contact" : {
"id":2,
"image": "../media/video/Ai Motion5.mp4",
"title" : "Contact",
"description":"sdadasdskdjaskljdas Team is Here to Save Your Time and Money.",
"buttonOne": "Get A Demo"
}
}
}
Home file:
import React, { Component } from 'react'
import LandingPage from "./landingPage/LandingPage"
import WaveSection from './waveSection/WaveSection'
import MyReview from "./reviewSection/MyReview"
import './styles/style.css'
import data from '../../json/data.json';
class Home extends Component{
render(){
return(
<div id='home' className='home'>
<LandingPage
title = {data['landing page'].home.title}
img = {data['landing page'].home.image}
description ={data['landing page'].home.description}
btn = {data['landing page'].home.buttonOne}
/>
<WaveSection/>
<MyReview/>
</div>
)
}
}
export default Home
Contact File:
import React, { Component } from 'react'
import video from '../../media/video/Ai Motion.mp4';
class Contact extends Component{
render(){
return(
<section className='contact-section landingPage-section'>
<div className="container">
<video autoPlay muted loop="True" id='myVideo' src={video}></video>
</div>
</section>
)
}
}
export default Contact
I will go with the first option (not storing it in state) as this data is static and the app does not modify it directly.

Vue - Pass components to router-view on dynamically loaded component

I need to render a different layout for the same route for a specific URI with different components depending on the user being on mobile or in desktop.
I would like to avoid having route path checks in the PageCommon(layout component) to keep it clean.
The app has a main component taking care of the layout, it has different router-views where we load the different components for each page URI. This would be a normal route for that.
{
path: '',
component: PageCommon,
children: [
{
path: '',
name: 'Home',
components: {
default: Home,
header: Header,
'main-menu': MainMenu,
'page-content': PageContent,
footer: Footer,
'content-footer': ContentFooter
}
},
I can't change the route components property once the component is loaded so I tried to make a wrapper and pass the components dynamically.
{
path: 'my-view',
name: 'My_View',
component: () => import('#/components/MyView/ViewWrapper')
},
In /components/MyView/ViewWrapper'
<page-common v-if="isMobile">
<my-mobile-view is="default"></my-mobile-view>
<main-menu is="main-menu"></main-menu>
</page-common>
<page-common v-else>
<my-desktop-view is="default"></my-desktop-view>
<header is="header"></header>
<main-menu is="main-menu"></main-menu>
<footer is="footer"></footer>
</page-common>
</template>
I would expect that the components passed inside page-common block would be substituted on the appropriate , but is not how it works, and Vue just loads page-common component with empty router-views.
Is there any approach for this?
Note that I already tried using :is property for loading different components, but the problem then is on how to tell the parent to use this or that component for this page. This is the code for that:
<template>
<component :is="myView"></component>
</template>
<script>
import DesktopView from "#/components/MyView/DesktopView";
import MobileView from "#/components/MyView/MobileView";
export default {
name: 'MyView',
components: {
DesktopView,
MobileView,
},
data(){
return {
myView: null,
isMobile: this.detectMobile()
}
},
methods : {
getViewComponent() {
return this.isMobile ? 'mobile-view' : 'desktop-view';
}
},
created() {
this.myView = this.getViewComponent();
}
}
</script>
I could use this approach for each of the PageCommon router views, creating a component for each that does the above, but it looks like a very bad solution.
A computed method is all you need.
You should have this top level Logic in App.vue and the <router-view> should be placed in both DesktopView and MobileView.
// App.vue
<template>
<component :is="myView"></component>
</template>
<script>
import DesktopView from "#/components/MyView/DesktopView";
import MobileView from "#/components/MyView/MobileView";
export default {
name: 'MyView',
components: {
DesktopView,
MobileView,
},
computed: {
myView() {
return this.detectMobile() ? 'mobile-view' : 'desktop-view';
}
}
}
</script>
You may also want to consider code splitting by setting up Dynamic Components for those layouts since Mobile will load Desktop View because it is compiled into final build, register them globally as dynamic imports instead if importing them in MyView and then delete components also after doing the following instead, this way only the one that is needed will be downloaded saving mobile users their bandwidth:
// main.js
import LoadingDesktopComponent from '#/components/LoadingDesktopComponent '
Vue.componenet('desktop-view', () => ({
component: import('#/components/MyView/DesktopView'),
loading: LoadingDesktopComponent // Displayed while loading the Desktop View
})
// LoadingDesktopComponent .vue
<template>
<div>
Optimizing for Desktop, Please wait.
</div>
</template>
<script>
export default {
name: 'loading-component'
}
</script>
Routing logic will only be processed when <router-view> is available,this means you can delay the presentation of Vue Router, for example you can have :is show a splash screen like a loading screen on any URI before displaying a component in :is that contains <router-view>, only than at that point will the URI be processed to display the relevant content.

How to make a Dynamic dropdown done in React with SQL database

I'm building a react app using facebook's:
https://github.com/facebookincubator/create-react-app
I´m new to react and I havent done a dropdown menu before. I have read a lot in the web and I figure I maybe need to use the select and options tags?
I want to have 4 image buttons as I call Main menu (three of the buttons will be able to navigate directly to the picked page).
The last image button will show an undermenu with 12 options pages to go to.
Option Option Option Option
Undermenu
12 options
I´m unsure where I shall begin, right now I have done some coding before I knew I needed to connect it to the SQL database.
App.js:
import React, { Component } from 'react';
import './sass/style.scss';
import Admin from "./components/routes/Admin";
import DropdownMenu from "./components/DropdownMenu";
class App extends Component {
render() {
return (
<div className="App">
<Admin />
<DropdownMenu />
<p className="TEST"> lorem imsum </p>
</div>
);
}
}
export default App;
DropdownMenu.js component:
import React from 'react';
import main_menu_home from '../images/Buttons/main_menu_home.png';
import main_menu_dragons from '../images/Buttons/main_menu_dragons.png';
import main_menu_dragon_test from '../images/Buttons/main_menu_dragon_test.png';
import main_menu_fortune_cookie from '../images/Buttons/main_menu_fortune_cookie.png';
const DropdownMenu = props => (
<header>
<nav>
<div className="dragonMenu-container">
<div className="dragonMenu">
<ul>
<li>
<img
id="Home"
className="Main_home"
src={main_menu_home}
alt="Home_button_image"
/>
</li>
<li>
<img
id="Dragons"
className="Main_Dragons"
src={main_menu_dragons}
alt="Dragons_button_image"
/>
</li>
<li>
<img
id="Dragon_test"
className="Main_Dragon_test"
src={main_menu_dragon_test}
alt="Dragon_test_button_image"
/>
</li>
<li>
<img
id="Fortune_cookie"
className="Main_fortune_cookie"
src={main_menu_fortune_cookie}
alt="Fortune_cookie_button_image"
/>
</li>
</ul>
</div>
</div>
</nav>
</header>
);
export default DropdownMenu;
Here the code just display four images which it gets from the images/Buttons folder. Maybe you don´t need so many imports and can get all the images with just a proper link to the image but I donno how to.
I think I need a global variable that pointing where all my images are so I can just have to invoke said variable to access the folder where the pictures are.
Ideas?
But back to the Dropdown problem:
I guess I need to create a table in my Sql?
But I donno how.
My problem is that I think of all things at the same time I need to do, but can´t easy myself to do one thing at the time.
I have more code for when I before fetched all from another table if you want to see that code as well.
Any questions, feel free to ask away :)
// Dragoness
UPDATED 18 sep 2019:
Right now, I have come this far:
I can now talk to the SQL database with react and print out some data from the SQL database itself. My problem now is that I just see broken images, does anyone have a solution for my problem?
What I see on the browser
My SQL database menus table with 4 columns
What I wrote in the browse tag to enter my data
Where I have MainMenu.js file and where I want the Buttons images from
App.js:
import React, { Component } from 'react';
import './sass/style.scss';
import Admin from "./components/routes/Admin";
import DropdownMenu from "./components/DropdownMenu";
import MainMenu from "./components/MainMenu";
class App extends Component {
render() {
return (
<div className="App">
<Admin />
<DropdownMenu />
<MainMenu />
<p className="TEST"> lorem imsum </p>
<div><img src='./images/Buttons/main_menu_home.png'/> </div>
</div>
);
}
}
export default App;
fetchMenu.php:
<?php
/* This file fetches current menus . */
include_once 'database.php';
$statement = $pdo->prepare("SELECT * FROM menus ORDER BY picUrl ASC");
$statement->execute();
$data = $statement->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data, JSON_PRETTY_PRINT);
?>
MainMenu.js:
import React, { Component } from 'react';
import "../App.scss";
class DropDownMenu {
id: 0;
picUrl: "";
linkUrl: "";
isSubmenu: "";
}
class MainMenu extends Component {
constructor(props) {
super(props);
this.state = {
allMenus: []
}
}
fetchAllMenus = () => {
fetch("http://localhost/dragonology/server/fetchMenu.php")
.then(response => response.json())
.then(data => {
console.log(data);
this.setState({ allMenus: data });
});
}
componentDidMount() {
this.fetchAllMenus();
}
render() {
let menu = this.state.allMenus.map((item) => {
return (<div key={item.id}><img src={item.picUrl} alt="dropdownmenu_main_and_under"/> - {item.linkUrl} - {item.isSubmenu}</div>)
});
console.log(menu);
return (
<div>{menu}</div>
);
}
}
export default MainMenu;
Thank you in advance
// Dragoness
Updated 19 sep 2019 with solution
I got some tips from those links:
I changed my images folder to be in the public instead of in src:
getting broken image in React App
Started to see a pattern that most of the tables with an image inside have some kind of "name" column, at least it worked for me:
https://www.youtube.com/watch?v=lTyks6s6b6E
All my success steps I took:
Fixed:
1. I added a folder called images inside the public folder.
2. Added one image of the main menu that I called home.
3. Went to the SQL database, deleted the old rows I tried to display the
data from that you can see on the browse tab that was inside the table
menus.
4. Added another column called picName. Took it as a varchar with 60 in
lengh.
5. Changed the settings on the picUrl to be a varchar with the lengh of
255 instead of 100 that I had before.
6. I did a test using the insert tab selection to add a row with the image
link I had before with the dot dot slash and it worked!.
7. Added 15 more rows(all main and undermenu buttons with its data).
8. After that I changed the folder structure again to have images/Buttons
and added all the button images that I had inside the src folder before.
9. Deleted all the images that were on the old folder.
10. Fixed: App.js took away the import of the DropDownMenu.js component and that it didnt print out my DropDownMenu.js component anymore.
App.js:
import React, { Component } from 'react';
import './sass/style.scss';
import Admin from "./components/routes/Admin";
import MainMenu from "./components/MainMenu";
class App extends Component {
render() {
return (
<div className="App">
<Admin />
<MainMenu />
<p className="TEST"> lorem imsum </p>
<div><img src='./images/Buttons/main_menu_home.png'/> </div>
</div>
);
}
}
export default App;
I couldn´t add the images of how my SQL database look now instead of before/where I find my images now in what folder because am new in Stack Overflow and don´t have enough reputation apperely. But those above are the steps I took to solve my problem :)

Inject content in component from other component using Vue

I have your usual admin dashboard (Core-UI) which I'm modifying for my own needs. I have an "aside" component into which I want to load MonitorAside.vue whenever I am on the Monitor page (I am using vue-router)
Here's a small rundown.
src/containers/Full.vue imports all the main components (including aside) and then uses router-view to render the view based on the route.
src/components/Aside.vue is the component in question. It contains fixed content but I want its content to dynamically be changed if another component requires to do so.
src/views/Monitor.vue is the page in question and thus the page which dynamically needs to inject/swap the content of the aside component. Note that this component is not imported in Full.vue but is rendered through the router there.
src/views/asides/MonitorAside.vue is the component I want to be loaded into Aside.vue whenever I am on the Monitor page.
How would I go about doing this?
So whenever vue-router navigates to a different page, you want the content of your Aside component to change? You can watch the $route value and then render the content depending on your route names, something like:
<template>
<div>
<monitor-aside v-if="page === 'monitor'"></monitor-aside>
<div v-else>
<!-- your default aside content -->
</div>
</div>
</template>
<script>
import MonitorAside from '../views/asides/MonitorAside.vue'
export default {
data() {
return {
page: null
}
},
methods: {
setContent(routeName) {
if (routeName === 'Monitor') {
this.page = 'monitor';
} else {
this.page = null;
}
}
},
created() {
this.setContent(this.$route.name);
},
watch: {
'$route'(to, from) {
this.setContent(to.name);
}
}
components: {
MonitorAside
}
}
</script>

Apanding external HTML to a react component is not working

Basically I want to add an static HTML to a react component from external script.
So I'm saving the reference of this to window variable as follows:
let { PropTypes } = React;
export default class Body extends React.Component {
constructor(){
super();
let frmTrgt={};
frmTrgt.refff=this;
console.log("tthis: ",this);
window.bdyRefrence=frmTrgt;
}
static defaultProps = {
items: []
};
static propTypes = {
items: PropTypes.array.isRequired
};
render() {
return (
<div className={styles.body}>
<h1 className={styles.header}>React Seed</h1>
<p>This is an example seed app, powered by React, ES6 & webpack.</p>
<p>Here is some example data:</p>
<Menu items={this.props.items} />
<div>
<h1>Dynamic Content</h1>
<div id="myDynamicContent"></div>
</div>
</div>
);
}
}
and in my script tag in INDEX.html( Outside Script) I'm doing like following:
function addPHtml() {
try {
window.bdyRefrence.refff.refs.formTarget.insertAdjacentHTML("<p id='mhere'>paragraph 2</p>");
}catch (err){
console.log("err: ",err);
}
}
but when I'm calling addPHtml it is giving following error:
err: TypeError: Cannot read property 'insertAdjacentHTML' of undefined
at addPHtml ((index):19)
at <anonymous>:1:1
What your trying to do is not the correct way to insert the element in React, still for you requirement please refer below mentioned code
Your render function should be like
return(
<div>
<div ref="formTarget"></div>
<h1 >React Seed</h1>
<p>This is an example seed app, powered by React, ES6 & webpack.</p>
<p>Here is some example data:</p>
<div>
<h1>Dynamic Content</h1>
<div id="myDynamicContent"></div>
</div>
</div>
)
Please check Demo here Demo
In case using new React syntax (Createclass is deprecated now) use
window.refferedItem.refs.formTarget.getDOMNode().insertAdjacentHTML

Categories