Splitting code into files using context api - reactjs

I'm using context API for the first time.I can understand how to write the code in a single page.But I can't understand how to split it into several files.When I split it as below it gives me an error saying that I have not exported MyProvider.But I have done it.I searched for many video tutorials but I couldn't find a one that matches to my problem
App.js
import {MyProvider} from './Context';
import {myContext} from './Context';
class Name extends Component {
render() {
return (
<div>
<myContext.Consumer>
{(context) => (
<React.Fragment>
<h1>Hello, {context.state.name}</h1>
<h3>{context.state.address}</h3>
</React.Fragment>
)}
</myContext.Consumer>
</div>
);
}
}
class Age extends Component {
render() {
return (
<div>
<myContext.Consumer>
{(context) => (
<React.Fragment>
<h1>You are {context.state.age} years old</h1>
<h3>You were born in - {context.state.dob}</h3>
</React.Fragment>
)}
</myContext.Consumer>
</div>
);
}
}
class App extends Component {
render() {
return (
<MyProvider>
<div className="App">
<Name />
<Age />
</div>
</MyProvider>
);
}
}
export default App;
Context.js
export const myContext = React.createContext();
class MyProvider extends Component {
state = {
name: "Sam",
address: "No.35,Main Street,Galle",
age: 50,
dob: "1970-10-21"
}
render() {
return (
<myContext.Provider value={{
state: this.state
}}>
{this.props.children}
</myContext.Provider>
)
}
}
export default MyProvider;

You have a mistake in import. When you export as default, you should import it without curly braces.
export default CLASS
import CLASS from
Or you can export your class as export class, then you will import it as you do:
export class A
import { A }
UPD:
Please take a look at
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export

Related

Cannot return a jsx inside a class component

I wanna set the condition to my cart so that when the cart's length is greater than 0, it will be rendered the CartList and CartColumns component. However, it cannot be rendered. I don't know what is wrong! Please help me to fix my codes! Thank you so much!
Cart.js:
import CartList from "./cart/CartList"
const ProductContext = React.createContext();
export default class Cart extends React.Component {
render() {
return (
<div>
<ProductContext.Consumer>
{(value) => {
return <div>
if(cart.length>0){
return(
<div>
<CartColums/>
<CartList/>
</div>
)
}
</div>
}}
</ProductContext.Consumer>
</div>
);
}
}
Sandbox link for better observation:https://codesandbox.io/s/why-cant-i-fetch-data-from-a-passed-value-forked-buz0u?file=/src/cart/Cart.js
You simply had a syntax error (which got highlighted by the codesandbox link btw). Consider using an editor / IDE that highlights simple errors like this one.
EDIT: To elaborate a little further on the syntax error:
After {(value) => {return <div> you inserted js wihout wrapping it in another pair of braces. In this case the solution was to remove the return <div> here entirely as it was unecessary.
import CartList from "./cart/CartList"
const ProductContext = React.createContext();
export default class Cart extends React.Component {
render() {
return (
<div>
<ProductContext.Consumer>
{(value) => {
if(cart.length>0){
return(
<div>
<CartColums/>
<CartList/>
</div>
)
}
}}
</ProductContext.Consumer>
</div>
);
}
}

It doesn't work Consumer/Provider in the example - the tab hangs

Why does the React tab in my browser hang when visualizing these components? What am I doing wrong? I just want to transfer the text to another component using Provider and Consumer.
Menu component:
import React, {PureComponent, createContext} from 'react'
import { Link } from "react-router-dom";
import './menu.scss';
import ShoppingBasket from '../shoppingBasket/shoppingBasket.js';
const UserContext = React.createContext({})
export const UserProvider = UserContext.Provider
export const UserConsumer = UserContext.Consumer
export default class Menu extends PureComponent {
render() {
return (
<div className="head">
<nav>
<Link to="/">Home</Link>
<Link to="/aboutus">About Us</Link>
</nav>
<UserProvider username={`name`}>
<ShoppingBasket />
</UserProvider>
</div>
)
}
}
ShoppingBasket component:
import React, {PureComponent} from 'react'
import UserProvider from '../menu/menu.js';
import UserConsumer from '../menu/menu.js';
export default class ShoppingBasket extends PureComponent {
render() {
return (
<UserConsumer>
{context => {
return(
<div>
<h2>Profile Page of {context.username}</h2>
</div>
)
}}
</UserConsumer>
)
}
}
As per the React Context Api ,in Context Provider, data should be passed using the "value" prop , what you are doing it passing the username prop to the provider, what you should try is
<UserProvider value={`name`}>
<ShoppingBasket />
</UserProvider>
and while in the consumer
<UserConsumer>
{value => {
return(
<div>
<h2>Profile Page of {value}</h2>
</div>
)
}}
</UserConsumer>

Creating A react component which can be nested

I am trying to create a component which can be reused in another component.Suppose i have a component like this
import React from 'react';
export default class Container extends React.Component {
render() {
return (
<div className='col-md-4/6/7'>
<div className='bg-dark'>
.......... Content Goes Here .............
</div>
</div>
);
}
}
Then i want to use the component like this...
import React from 'react';
export default class Container extends React.Component {
render() {
return (
<Container col md={4}>
.......... Content Goes Here .............
</Container>
);
}
}
I cant achieve that .It can be somewhat {this.state.children} but dont know how can achieve it
Simply edit the Container to render children:
import React from 'react';
export default class Container extends React.Component {
render() {
return (
<div className='col-md-4/6/7'>
<div className='bg-dark'>
{ this.props.children }
</div>
</div>
);
}
}
And then use it:
<Container col md={4}>
Hello, world!
</Container>
The children prop is explained in detail here: https://reactjs.org/docs/composition-vs-inheritance.html
Props.children
const Wrapper = (props) => <div>{props.children}</div>
const Inner = (props) => <Wrapper>some text or component</Wrapper>
Access using this.props.children because it's class based component. if it's functional component access using props.children
export default class Container extends React.Component {
render() {
return (
<div className='col-md-4/6/7'>
<div className='bg-dark'>
{this.props.children}
</div>
</div>
);
}
}

react - children component not showing

I'm trying to insert a child component inside another child component, but my code is not working. Following codes are the structure i'm trying to build.
const AddProductPage= () => {
return (
<PageTemplate>
<ProductTemplate>
<AddProduct />
</ProductTemplate>
</PageTemplate>
);
};
const PageTemplate= ({children}) => {
return (
<div className={cx('pagetemplate')}>
<HeaderContainer />
<main>
{children}
</main>
<Footer />
</div>
);
};
class ProductTemplate extends Component {
render() {
return (
<div className={cx('product-template')}>
...
<div className={cx('display')}>
{this.props.children}
</div>
</div>
);
}
}
class AddProduct extends Component {
render() {
return (
<div className={cx('addproduct')}>
addproduct
</div>
);
}
}
I'm trying to insert AddProduct component in ProductTemplate component as a child, which is inserted in PageTemplate component as a child. AddProductPage, however, is not showing AddProduct component. I'd be grateful if anyone can help.
I've run your code. May be you'r missing default export statements.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import AddProductPage from './AddProductPage';
ReactDOM.render(<AddProductPage />, document.getElementById('root'));
AddProductPage.js
import React from 'react';
import PageTemplate from './PageTemplate';
import ProductTemplate from './ProductTemplate';
import AddProduct from './AddProduct';
const AddProductPage= () => {
return (
<PageTemplate>
<ProductTemplate>
<AddProduct />
</ProductTemplate>
</PageTemplate>
);
};
export default AddProduct;
PageTemplate.js
import React from 'react';
const PageTemplate= ({children}) => {
return (
<div>
<main>
{children}
</main>
</div>
);
};
export default PageTemplate;
ProductTemplate.js
import React,{Component} from 'react';
class ProductTemplate extends Component {
render() {
return (
<div>
<div>
{this.props.children}
</div>
</div>
);
};
};
export default ProductTemplate;
AddProduct.js
import React, {Component} from 'react';
class AddProduct extends Component {
render() {
return (
<div>
addproduct
</div>
);
};
};
export default AddProduct;
Output is this :
addproduct
Here`s a Fiddle of your code
Works Fine!. I have removed cx API. I suppose the problem might be with className resolution. Check in the dom hierarchy weather the Children DOM Node exists and they have received their respective classnames.
const PageTemplate= ({children}) => {
return (
<div className={'pagetemplate'}>
<HeaderContainer />
<main>
{children}
</main>
<Footer />
</div>
);
};

While using React Context API ,unable to fetch data

This is my App.js , I am using context api but I am unable to fetch
data at {context.country} and {context.job} which is in child
component i.e Neighbour.
This is my App.js , I am using context api but I am unable to fetch
data at {context.country} and {context.job} which is in child
component i.e Neighbour.
App.js
import React, { Component } from 'react';
import Neighbour from './Neighbour';
const MyContext = React.createContext();
class MyProvider extends Component {
state = {
firstName: 'Tom', lastName: 'Holland', age: 24, country: 'America', job: 'Actor',
}
render() {
return (
<MyContext.Provider value={{
state: this.state, growOld: () => this.setState({ age: this.state.age + 1 })
}}>
{this.props.children}
</MyContext.Provider>
);
}
}
class App extends Component {
render() {
return (
<div className="App">
<MyProvider value={{ state: this.state }}>
<div>
<p>I am in App component</p>
<Family />
<br />
<Neighbour />
</div>
</MyProvider>
</div>
);
}
}
export default App;
Neighbour.js
import React, { Component } from 'react';
const MyContext = React.createContext();
class Neighbour extends Component {
constructor(props){
super(props)
}
render() {
return (
<div>
<MyContext.Consumer>
{context => (
<React.Fragment>
<p>Country : {context.country}</p>
<p>Job : {context.job}</p>
</React.Fragment>
)}
</MyContext.Consumer>
</div>
);
}
}
export default Neighbour;
Since you are providing the value as object {state: this.state} to context, you need to use it like context.state.country in your consumer.
<MyContext.Consumer>
{context => (
<React.Fragment>
<p>Country : {context.state.country}</p>
<p>Job : {context.state.job}</p>
</React.Fragment>
)}
</MyContext.Consumer>
or you Provide the value in provider like
<MyProvider value={this.state}>
<div>
<p>I am in App component</p>
<Family />
<br />
<Neighbour />
</div>
</MyProvider>
Also in Neighbour component you re creating a context again which doesn't have a Provider and hence the value in Consumer would come undefined, you need to import the same context that you have used the Provider on
In Neighbour.js
Neighbour.js
import React, { Component } from 'react';
inport { MyContext } from 'path/to/context';

Resources