I'm trying to render a different background image for a child component depending on the URL that is passed through props.
The background images are stored in the public folder under a file called images
public/images/bg_1.jpg
Current I have this:
Parent component
import React from "react";
import Nav from "./Nav";
import SubNav from "./SubNav";
import Footer from "./Footer";
import PageHero from "./PageHero";
import backgroundImage from '../../public/images/bg_1.jpg';
const MainPage = () => (
<div>
<Nav />
<SubNav company="Main Company" />
<PageHero BackgroundURL={backgroundImage}/>
<Footer />
</div>
);
export default MainPage;
Child component (PageHero)
import React from "react";
export class PageHero extends React.Component {
render(props) {
return (
<div>
<div
class="page-hero uk-light"
style={{ backgroundImage: `url(${props.BackgroundURL})` }}
>
<div class="uk-container uk-container-medium uk-text-center">
<h1 class="uk-heading-primary page-hero__header uk-animation-fade">
Page Heder
</h1>
</div>
</div>
</div>
);
}
}
export default PageHero;
But I get this error when I try to link the src:
ERROR in ./public/images/bg_1.jpg
You may need an appropriate loader to handle this file type.
is this possibly an issue with webpack or the way I'm referencing the image?
Related
I am following along a beginner's course on React. The Nav. Bar has two options - About, HomePage. On clicking on the bar, the url gets updated but the page remains the same and nav stays. I get no error.
App.js
import React from 'react';
import HomePage from './HomePage';
import About from './About';
import Header from './common/Header';
function App() {
function getPage() {
const route = window.location.pathname;
if (route === "about") return <About />;
console.log("hi");
return <HomePage />;
}
return(
<div className="container-fluid">
<Header>
{ getPage() }
</Header>
</div>
);
}
export default App;
Header.js
import React from 'react';
//to navigate across the website
function Header(){
return (
<nav>
Home | About
</nav>
);
}
export default Header;
index.js
import "bootstrap/dist/css/bootstrap.min.css";
import React from "react";
import {render} from "react-dom";
import App from "./components/App";
render(<App />, document.getElementById("root"));
About.js
import React from 'react';
class About extends React.Component{
render (){
return(
<>
<h1> About </h1>
<p> This is the About Page </p>
</>
);
}
}
export default About;
HomePage.js
import React from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
function HomePage(){
return(
<div className="jumbotron">
<h1>
Welcome
</h1>
<p>
This is my first React Project
</p>
</div>
);
}
export default HomePage;
There is no change in the page, only the URL gets updated.
I have tried many solutions on SO but none worked so far.
I'm guessing it always displays the <HomePage /> component?
That's because window.location.pathname returns a path with a leading slash. So route === "about" will always be false. You need to check route === "/about" instead.
In getPage function condition is wrong it's not about it's will be /about
Just change condition in if statement
like this
if (route === "/about") return <About />;
I'm new to React Native. This is my error:
My code looks like this:
Toolbar.js
import React from 'react';
const Toolbar = props => (
<header>
<nav>
<div></div>
<div>THE LOGO</div>
<div>
<ul>
<li>Products</li>
<li>Users</li>
</ul>
</div>
</nav>
</header>
);
export default Toolbar;
App.js
import React, { Component } from 'react';
import Toolbar from './components/Toolbar/Toolbar'
class App extends Component {
render() {
return (
<div className="App">
<Toolbar />
</div>
);
}
}
export default App;
index.js
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('albums', () => App);
This is due to the components in your Toolbar not having capital letters. On further investigation you can see that you are trying to use html tags. You can’t use html tags in React-Native. Tags like <div>, <header>, <nav> etc. have no value in React-Native.
You need to use React-Native components like <View> or <Text> to construct your views.
I am using BrowserRouter of react through which I want to navigate between pages. Initially there are four images in a page, and after clicking on one image, the image opens up in the screen. There is a back button below that image, which navigates the user back to the first screen with four images.
The code is like this
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import {FirstPage} from './FirstPage.js';
import {BrowserRouter,Route,Router} from 'react-router-dom';
class App extends React.Component{
constructor(props){
super(props);
}
render(){
return(
<div>
<BrowserRouter>
<Route path="/" component={FirstPage}><FirstPage/></Route>
</BrowserRouter>
</div>
)
}
}
ReactDOM.render(<App/>,document.getElementById('container'));
FirstPage.js
class FirstPage extends React.Component{
constructor(props){
super(props);
this.state={
list:[],
images:[],
isClicked:false
}
this.loadImages=this.loadImages.bind(this);
this.loadOne=this.loadOne.bind(this);
}
componentDidMount(){
window.addEventListener('load',this.loadImages);
}
loadImages(){
console.log("load");
var that=this;
$.ajax({
type:'GET',
url:'https://demo0813639.mockable.io/getPanos',
datatype:'jsonp',
success:function(result){
var images=that.state.images;
for(var i=0;i<result.length;i++){
that.state.images.push({"pano":result[i].pano,"name":result[i].name});
}
that.setState({
images:images
})
}
})
}
loadOne(pano){
this.setState({
isClicked:true,
imageUrl:pano
})
}
render(){
var list=this.state.list;
if(this.state.isClicked===false){
list=this.state.images.map((result)=>{
//console.log(result.name);
return(<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image col-md-3" onClick={this.loadOne.bind(this,result.pano)}/>
</div>
)
})
}
else{
list.push(<Panorama imageUrl={this.state.imageUrl}/>)
}
return <div>{list}</div>;
}
}
module.exports={
FirstPage:FirstPage
}
Panorama.js
import 'aframe';
import 'aframe-particle-system-component';
import {Entity, Scene} from 'aframe-react';
import {Link} from 'react-router-dom';
class Panorama extends React.Component{
render(){
return(
<div>
<div className="pano">
<Scene>
<a-assets position="5 5 5">
<img id="myImage" src={this.props.imageUrl} crossorigin="anonymous"/>
</a-assets>
<a-sky src="#myImage"></a-sky>
</Scene>
</div>
<div className="goback"><Link to="/">Go back</Link></div>
</div>
)
}
}
module.exports={
Panorama:Panorama
}
There aren't any errors for the above code, but it doesn't work too. The version of react router is v4. What is wrong above?
It seems like you aren't really taking advantage of React Router here. The reason why the <Link/> doesn't do anything is because you're technically still on the same page as your image box, as you're not moving to another path, therefore the link would not trigger a path change.
I've created a quick example on how you can get past this issue. Of course it's not an exact replica of your project but it gives you an idea of how you can solve this issue.
=== Explanation
Main App
Our Main app consists of two routes. One for selecting an image and the other for viewing an image.
View Image
This displays an image that was sent across by the First Page component. This is one way to do it but you could also store images and active image in App Component and send it down to this child component so that you don't have to keep the image url in the parameter. (OR you could use Redux or some other global state manager).
First Page
We list a series of images via a simple array and keep an active index of the select image. We map these to the view via buttons and trigger an event once they have been clicked on which sets the active image and redirect flag that will redirect the user to the image/:id route with the image url.
Of course, your loading of images can be improved but that's out of scope for this question.
View working version here: https://codesandbox.io/s/pY2LyzAEr
=== Source
import React from 'react';
import { render } from "react-dom";
import { BrowserRouter, Route, Router, Redirect, Switch, Link } from 'react-router-dom';
// *-------------------------
// | First Page
// *-------------------------
class FirstPage extends React.Component{
state = {
currentActive: null,
redirect: false,
images: ['https://cdn.pixabay.com/photo/2014/12/22/10/04/lion-577104__340.jpg', 'http://www.yosemite.com/wp-content/uploads/2013/07/Merced-Lake-back-of-Half-Dome_Kenny-Karst.jpg', 'http://www.japan-guide.com/g9/3060_12.jpg', 'https://cache-graphicslib.viator.com/graphicslib/thumbs674x446/3675/SITours/hong-kong-island-half-day-tour-in-hong-kong-114439.jpg']
}
viewImage = (evt) => {
this.setState({
currentActive: evt.target.dataset.image,
redirect: true
})
}
render(){
return this.state.redirect
? <Redirect to={`/image/${btoa(this.state.images[this.state.currentActive])}`} />
: (
<div>
{this.state.images.map((image, index) => {
return <button key={index} data-image={index} onClick={this.viewImage}>View Image {index + 1}</button>
})}
</div>
)
}
}
// *-------------------------
// | View Image Component
// *-------------------------
const ViewImage = (props) => {
return (
<div>
<img src={`${atob(props.match.params.id)}`} />
<div><Link to="/">Back</Link></div>
</div>
)
}
// *-------------------------
// | Main App.JS
// *-------------------------
class App extends React.Component {
render(){
return(
<div>
<BrowserRouter>
<Switch>
<Route exact path="/" component={FirstPage}/>
<Route path="/image/:id" component={ViewImage}/>
</Switch>
</BrowserRouter>
</div>
)
}
}
render(<App />, document.getElementById("root"));
I am trying to develop a webapp using reactjs and i have a issue. After more than 1 day of research, i don't understand how to do.
I want to use a component which are the main layout of my page adding other component to display in it.
In the component Base2, the child props contains another component.
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base2 = (child) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
<child/> // HERE the dynamic component
</div>
);
export default Base2;
The function calling it is :
const TestBase = ({props}) => {
return (<Base child={MyComponent}/>)
};
Moreover MyComponent can be a class declare following 2 methods:
import React from 'react';
import LoginForm from '../components/LoginForm.jsx';
class MyComponent extends React.Component{
constructor(props) {
super(props);
...
}
render() {
return (
<LoginForm
onSubmit={this.processForm}
onChange={this.changeUser}
errors={this.state.errors}
user={this.state.user}
/>
);
}
}
export default LoginPage;
Second method :
import React from 'react';
import { Card, CardTitle } from 'material-ui/Card';
const MyComponent = {
render() {
return (<Card className="container">
<CardTitle title="React Application" subtitle="Home page." />
</Card>);
}
};
export default MyComponent ;
During my tests, only the second method works. The lack of "instance" (something like that i guess) from the second method might be the issue?
How can I develop Base2 component to take these 2 types of component declaration?
Thanks in advance for your help
First pass the component like this:
<Base child={<MyComponent/>}/>
Then render it inside Base2 component by props.child, the way you wrote the Base2 component, child (just the argument name) will have the value of props not directly the component you are passing in props.
Write it like this:
const Base2 = (props) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{props.child} //here
</div>
);
In the second method seems to be a simple json containing a render method. To create component in your second method which seems to be wrote in es5 you have to use react.createClass({ render ... })
Seek on internet you will find a lot of es5 example
With the help of #Mayank Shukla i found the best way to do.
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base2 = (props) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{props.child}
</div>
);
export default Base2;
The function calling it is :
const TestBase = (props) => {
return (<Base2 child={<MyComponent/>}/>)
};
First Method:
import React from 'react';
import LoginForm from '../components/LoginForm.jsx';
class MyComponent extends React.Component{
constructor(props) {
super(props);
...
}
render() {
return (
<LoginForm
onSubmit={this.processForm}
onChange={this.changeUser}
errors={this.state.errors}
user={this.state.user}
/>
);
}
}
export default LoginPage;
Second method :
import React from 'react';
import { Card, CardTitle } from 'material-ui/Card';
const MyComponent = (props) =>{
return (<Card className="container">
<CardTitle title="React Application" subtitle="Home page." />
</Card>);
};
export default MyComponent ;
I'm using nativebase as a base for the UI side of a React Native app that I'm developing and I'm running into an error with something that should be very simple.
I want to create a component for the tab footer of the app to include in different views as follows:
./Components/Footer.js
import React, { Component } from 'react';
import {
Footer,
FooterTab,
Button,
Icon,
Text
} from 'native-base';
class TabFooter extends Component {
render() {
return (
<Footer >
<FooterTab>
<Button>
<Badge>2</Badge>
Apps
<Icon name='ios-apps-outline' />
</Button>
<Button>
Camera
<Icon name='ios-camera-outline' />
</Button>
<Button active>
Navigate
<Icon name='ios-compass' />
</Button>
<Button>
Contact
<Icon name='ios-contact-outline' />
</Button>
</FooterTab>
</Footer>
);
}
}
export default TabFooter;
And an example view would be:
import React, { Component } from 'react';
import { Container, Header, Title, Content, Footer, FooterTab, Button, Icon,
Text, List, ListItem, Input, InputGroup } from 'native-base';
import { TabFooter } from '../Components/Footer';
class EditGuest extends Component {
render() {
return (
<Container>
<Header>
<Title>Whatever title</Title>
</Header>
<Content>
</Content>
<TabFooter />
</Container>
);
}
}
export default EditGuest;
But when this view renders I'm getting the error:
ExceptionsManager.js:82 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `EditGuest`.
Is there something really basic that I'm missing because I would of thought that I could just simply include this component within any view without any problems...
Since you're doing a default export, you should remove {} from your import:
import TabFooter from '../Components/Footer';
see Why es6 react component works only with "export default"?
myFooter.js
import React, { Component } from 'react';
import { Footer, FooterTab, Button, Icon, Badge } from 'native-base';
class TabFooter extends Component {
render() {
return (
<Footer>
<FooterTab>
<Button>
<Badge>2</Badge>
Apps
<Icon name="ios-apps-outline" />
</Button>
<Button>
Camera
<Icon name="ios-camera-outline" />
</Button>
<Button active>
Navigate
<Icon name="ios-compass" />
</Button>
<Button>
Contact
<Icon name="ios-contact-outline" />
</Button>
</FooterTab>
</Footer>
);
}
}
export default TabFooter;
EditGuest.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { Container, Header, Title, Content } from 'native-base';
import TabFooter from './myFooter';
class EditGuest extends Component {
render() {
return (
<Container>
<Header>
<Title>Whatever title</Title>
</Header>
<Content />
<View>
<TabFooter />
</View>
</Container>
);
}
}
export default EditGuest;
Screenshot
Try to change:
import { TabFooter } from '../Components/Footer';
to
import TabFooter from '../Components/Footer';