I have a React app which now has two routes (the main landing page and career page).
I made one reusable JumbotronResponsive component and i am rendering that single component as child under JumbotronLanding component (for landing page) and as child under JumbotronCareer component (for career page).
Like this
import React, { PureComponent } from 'react'
import { ResponsiveJumbotron } from '../../HOC';
import './jumbotronCareer.css';
export default class JumbotronCareer extends PureComponent {
render() {
return (
<>
<ResponsiveJumbotron/>
</>
)
}
}
and this
import React, { PureComponent } from 'react';
import { ResponsiveJumbotron } from '../../HOC';
import './jumbotronLanding.css';
export default class JumbotronLanding extends PureComponent {
render() {
return (
<>
<ResponsiveJumbotron/>
</>
)
}
}
As you can see those parent components have styles in which i want to style some ResponsiveJumbotron's parts.
For example i wish font-size of jumbotron in landing page be 70px and in career page be 45px.
But when i switch between routes those styles are like in one CSS file.
The question is 'how to separate them from each other?'.
You can add a className property and in your ResponsiveJumbotron use it like
const ResponsiveJumbotron = props => <div className={props.className} />;
[...]
export default class JumbotronLanding extends PureComponent {
render() {
return (
<>
<ResponsiveJumbotron className="landing-page" />
</>
)
}
}
and you can use that css class in your stylesheet
Related
// -----App.js
import logo from './logo.svg';
import './App.css';
import Navbar from './components/Navbar';
import News from './components/News';
import NewsItem from './components/NewsItem';
function App() {
return (
<div>
<Navbar />
<News />
</div>
);
}
export default App;
// ----- News.js
import React, { Component } from 'react'
import NewsItem from './NewsItem';
export class News extends Component {
render() {
return (
<div>
<NewsItem />
</div>
)
}
}
export default News
//----- NewsItem.js
import React, { Component } from 'react'
export class NewsItem extends Component {
render() {
return (
<div>
NewItem component
</div>
)
}
}
export default NewsItem
I am new to react and trying to learn the basics.I tried to resolve the issue but couldn't find out the actual cause. I tried to search same issue over the internet but can't find any. All though the error msg is same but situation is different.
As you can see the NewsItem.js component is passed to News.js. Is it ok to pass a class component to another class component as a return type?
I'm getting the error as shown in img.
enter image description here
Try to remove export before defining the class
class News extends Component ...
class NewsItem extends Component ...
You are already default exporting it at the bottom
This question is specifically for react-router-dom version 5.
Here's my App component following the structures of the quick start guide:
import React, { Component } from "react";
import ProductDetails from "./components/productDetails";
class App extends Component {
render() {
return (
<Switch>
<Route path="/products/:id">
<ProductDetails />
</Route>
</Switch>
);
}
}
And here's my productDetails.jsx:
import React, { Component } from "react";
class ProductDetails extends Component {
render() {
return (
<h1>Product Details - {this.props.match.params.id}</h1>
);
}
}
export default ProductDetails;
which
How to get the this.props.match.params.id in class component way, not function way.
Also I found that the corresponding props empty:
but, those values are in Router.Provider:
So, how to get all the Route component's props from it's children using class?
Add withRouter HOC to your class component then you will have access to the this.props.match.params
import it from react-router
import { withRouter } from "react-router";
Then wrap your component with it like this
export default withRouter(ProductDetails);
I'm building an e-commerce website with React (my first ever React project) and I'm using React router to manage my pages.
I've got the following component tree structure:
<Router>
<BrowserRouter>
<Router>
<withRouter(Base)>
<Route>
<Base>
<BaseProvider>
<Context.Provider>
<Header>
<PageContent>
The standard React Router structure basically, and withRouter I've got the following:
Base.js
import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { Header } from './Header';
import { Footer } from './Footer';
import Provider from '../../BaseProvider';
class Base extends Component {
render() {
return (
<Provider>
<Header/>
<div className="container">{this.props.children}</div>
<Footer />
</Provider>
);
}
}
BaseProvider.js
import React, { Component, createContext } from 'react';
const Context = createContext();
const { Provider, Consumer } = Context;
class BaseProvider extends Component {
state = {
cart: [],
basketTotal: 0,
priceTotal: 0,
};
addProductToCart = product => {
const cart = { ...this.state.cart };
cart[product.id] = product;
this.setState({ cart, basketTotal: Object.keys(cart).length });
};
render() {
return (
<Provider
value={{ state: this.state, addProductToCart: this.addProductToCart }}
>
{this.props.children}
</Provider>
);
}
}
export { Consumer };
export default BaseProvider;
This gives me a template essentially, so I just the children pages without having to include Header and Footer each time.
If I want to use my global context I'm having to import it each time, and it seems like I've done something wrong as surely I should be able to use this on any page since it's exported in BaseProvider?
If I was to visit the About page, I'd get the same component structure, but no access to the consumer without using:
import { Consumer } from '../../BaseProvider';
Why do I have to do this for each file even though it's exported and at the top level of my BaseProvider? It just seems such a bad pattern that I'd have to import it into about 20 files...
Without importing it, I just get:
Line 67: 'Consumer' is not defined no-undef
I tried just adding the contextType to base but I get: Warning: withRouter(Base): Function components do not support contextType.
Base.contextType = Consumer;
I feel like I've just implemented this wrong as surely this pattern should work a lot better.
I'd recommend using a Higher Order Component - a component that wraps other components with additional state or functionality.
const CartConsumer = Component => {
return class extends React.Component {
render() {
return (
<MyContext.Consumer>
<Component />
</MyContext.Consumer>
)
}
}
}
Then in any component where you'd like to use it, simply wrap in the export statement:
export default CartConsumer(ComponentWithContext)
This does not avoid importing completely, but it's far more minimal than using the consumer directly.
I'm new to React and would like to keep all my components in one file. How do I export more than one component and keep them in the same file?
import React, { Component } from "react";
class MyText extends Component {
render() {
return (<div>
<h1>
Component</h1>
<p>This class component is named MyText. I can re-use it's code by simply Rendering (fancy name for calling) it by it's class name and I won't have to re type it, however many times I will need it.</p>
</div>);
};
}
class GreetName extends Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}</h1>;
</div>
);
};
}
export default MyText;
You can do as Jess Kenney said or use naming export at the bottom of your file:
SomeComponent.js
import React, { Component } from "react";
class MyText extends Component {
render() {
return (<div>
<h1>
Component</h1>
<p>This class component is named MyText. I can re-use it's code by simply Rendering (fancy name for calling) it by it's class name and I won't have to re type it, however many times I will need it.</p>
</div>);
};
}
class GreetName extends Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}</h1>;
</div>
);
};
}
export { MyText, GreetName };
And then use it like:
import { MyText, GreetName } from './SomeComponent'
I advice you to use one component per file, so you can keep your project modular. In ReactJS it's a convention to export one component from a file, and to export it is as the default export.
If it's helper component which used only in the particular you can put it to the same file as functional component.
Instead of using the export default line at the bottom, you can put export before each class definition, like export class GreetName... then to include your classes in another file you can use import {MyText, GreetName} from 'your/file.js'
export default secretContext;
export {taskData};
for export two function component
do this in app.js
export default App;
export{New_component};
do this in index.js
import App from './App';
import {Hari} from './App';
<App name={people.name}/>
<New_component msg={people.msg}/>
make sure component name start with capital letter
i am currently trying to solve a react problem.
i want to be able to add icons to a container called SalesChannels.
here is the code to the salesChannels page: (JSX)
import React, { Component } from 'react';
import PageContent from 'components/PageContent';
import IBox from 'components/IBox';
export default class SalesChannelsPage extends Component {
constructor(props) {
super(props);
this.state = {
rows: []
}
}
render() {
return (
<PageContent header="Salgskanaler">
<IBox title="Salgskanaler">
</IBox>
</PageContent>
);
}
}
As you can see, i have added a component called IBox. this should be reusable
it looks like this:
import React, {Component} from 'react';
import IBoxTools from './IBoxTools'
export default class IBox extends Component {
render() {
return(
<div className="ibox">
<div className="ibox-title">
{this.props.title}
//this is where the icon should be rendered in the dom
</div>
<div className="ibox-content">
{this.props.children}
</div>
</div>
);
}
}
i have also created another component called IBoxTools - this contains the actual icon / "i" tag:
import React, {Component} from 'react';
export default class IBoxTools extends Component {
render() {
let icon;
if(this.props.icon) {
icon = (
<a title={this.props.title}>
<i onClick={() => this.iconClicked()} className={`pull-right ${this.props.icon}`}></i>
</a>
);
}
return icon;
}
iconClicked() {
console.log('icon clicked')
}
}
So what i am trying to do is add multible icons to the SalesChannels page, inside the IBox tag, without making the IBox component dependent on it.
I hope you can help. Thanks!
You can pass components or arrays of components in props just like children
<IBox
title="Salgskanaler"
icons={[
<IBoxTools key="icon1" icon="foo" />,
<IBoxTools key="icon2" icon="bar" />
]}
>
{/* normal children here */}
</IBox>
Then inside IBox you write { this.props.icons } which will render the icons (or whatever else) if you pass it in.. otherwise will display nothing if the prop is undefined.
You could just use a condition if you don't want to display the icon every time. If I understand what you're attempting to do ...
import React, {Component} from 'react';
import IBoxTools from './IBoxTools'
export default class IBox extends Component {
render() {
return(
<div className="ibox">
<div className="ibox-title">
{this.props.title}
//this is where the icon should be rendered in the dom
{(condition) ? <IBoxTools /> : ""}
</div>
<div className="ibox-content">
{this.props.children}
</div>
</div>
);
}
}
Or if you need to do it multiple times, like you said, then I would use underscore.js or something like it that has a map function.
{_.map(icons, function(icon) {
return (
<IBoxTools />
)
})}
Or some combination of the two.