Right now, I have this code (showing generic):
import {useState} from 'react';
const parentComponent = () => {
const [show, setShow] = useState(false);
return
(<>
<childComponent setShowDependent={() => setShow(true)} />
{ show && <dependentComponent /> }
</>);
}
const childComponent = ({setShowDependent}) => {
return <Button onClick={setShowDependent} />;
}
and I am getting the warning in react dev tools:
Warning: Cannot update a component (`parentComponent`) while rendering a different component (`childComponent`).
and it is not working properly. What am I doing wrong?
React component name must start with an uppercase letter
import {useState} from 'react';
const ParentComponent = () => {
const [show, setShow] = useState(false);
return (<>
<ChildComponent setShowDependent={() => setShow(true)} />
{ show && <DependentComponent /> }
</>);
}
const ChildComponent = ({setShowDependent}) => {
return <Button onClick={setShowDependent} />;
}
I'm trying to add a login page to my existing app. Following along this tutorial https://www.digitalocean.com/community/tutorials/how-to-add-login-authentication-to-react-applications
Got stuck in step 3. My app is a class component, while in the tutorial it's a function component.
How can I convert this to a class component?
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Dashboard from '../Dashboard/Dashboard';
import Login from '../Login/Login';
import Preferences from '../Preferences/Preferences';
function setToken(userToken) {
sessionStorage.setItem('token', JSON.stringify(userToken));
}
function getToken() {
const tokenString = sessionStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken?.token
}
function App() {
const token = getToken();
if(!token) {
return <Login setToken={setToken} />
}
return (
<div className="wrapper">
...
</div>
);
}
export default App;
I've tried as below, but it says getToken is not defined inside of a render.
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';
import Dashboard from '../Dashboard/Dashboard';
import Login from '../Login/Login';
import Preferences from '../Preferences/Preferences';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
token: undefined
}
this.setToken = this.setToken.bind(this);
this.getToken = this.getToken.bind(this);
}
setToken(userToken) {
sessionStorage.setItem('token', JSON.stringify(userToken));
}
getToken() {
const tokenString = sessionStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken?.token;
}
render() {
const {token} = getToken(); /* In this line getToken is not defined */
if (!token) {
return <Login setToken={(newToken) => this.setState({ token: newToken })} />
}
return (
<div className="pomodoro-clock">
</div>
);
}
I see in the original code, getToken and setToken declared outside of an app. I've tried this, but anyway, getToken is not defined .
I can provide the full code if needed. Any help is appreciated.
If you want to make the functions members of the class, then you need to refer to it using this.getToken(), not just getToken();
render() {
const {token} = this.getToken();
Though since the getToken and setToken functions don't make any reference to this they don't actually need to part of the class. You could keep them outside the class, and refer to them the same way the function component refers to them:
function setToken(userToken) {
sessionStorage.setItem('token', JSON.stringify(userToken));
}
function getToken() {
const tokenString = sessionStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken?.token
}
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
const {token} = getToken();
// ...
}
}
I'm working on an app with expressjs and reactjs. I fetched the data from the backend using expressjs but I get map is not a function.
import React, { Component } from "react";
import "./products.css";
import Listofproducts from "./listofproducts";
import { Link } from "react-router-dom";
class products extends Component {
constructor(props) {
super(props);
this.state = {
productInfo: ""
};
}
async getProducts() {
try {
const data = await fetch("http://localhost:4000/product");
const jsonData = await data.json();
this.setState({
productInfo: jsonData
});
console.log(this.state.productInfo);
} catch (error) {
console.log(error);
}
}
componentDidMount() {
this.getProducts();
}
render() {
return (
<React.Fragment>
<Listofproducts itemlists={this.state.productInfo} />
</React.Fragment>
);
}
}
export default products;
Here is the component productLists where I sent the props to work with it.
import React, { Component } from "react";
import Product from "./products";
class Listofproducts extends Component {
render() {
const { itemslist } = this.props;
console.log(itemslist);
// console.log is working here i get back the data on the console
return itemslist.map(list => {
console.log(list);
});
}
}
export default Listofproducts;
You set productInfo to an empty string in the constructor of products, and strings don't have a map method.
Change the default value to an empty array instead and it will work just as well before and after your network request completes.
class Products extends Component {
constructor(props) {
super(props);
this.state = {
productInfo: []
};
}
// ...
}
I have created a e Commerce App in react. As you can see from the screenshot below, that when I click on the Apparels->Girls->Shoes , the data is not displayed in the screen.
So first, in the index.js file, I have set the BrowserRouter and created a component Main which holds all my other components.
index.js
import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
import "./index.css";
import 'bootstrap/dist/css/bootstrap.css';
import {Route, NavLink, BrowserRouter} from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<Main/>
</BrowserRouter>
)
,
document.getElementById("root")
);
After this I have created Main.js, where I have created components for Navigation and PLPMenu( which should display after clicking on the Girls->Shoes). Also in the Main.js, I have set the switch and Route paths
Main.js
import React, { Component } from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
import { Route, Switch } from 'react-router-dom';
import Navigation from "./components/topNavigation";
import Footer from "./components/Footer";
import Banner from "./components/Banner";
import PLPMenu from "./components/PLPMenu";
import PDP from "./components/PDP";
import Home from "./components/Home";
class Main extends Component {
render() {
return (
<div>
<Navigation />
<Switch>
<Route exact path="/" component={Home} />
<Route path="Apparel/Girls/:id" component={PLPMenu}/>
<Route path="/PDP" component={PDP} />
<Route path="/Banner" component={Banner} />
<Route path="/Footer" component={Footer} />
</Switch>
</div>
)
}
}
export default Main;
In the topNavigation.js, I'm displaying the first level of categories like Apparel, Electronics, Grocery etc. Also, I have created, a component SubMenu for displaying the second level of categories like Girls, Boys, Women etc.
topNavigation.js
import React, { Component } from 'react';
import axios from 'axios';
import SubMenu from './subMenu';
class Navigation extends Component {
state = {
mainCategory: []
}
componentDidMount() {
axios.get('http://localhost:3030/topCategory')
.then(res => {
console.log(res.data.express);
this.setState({
mainCategory: res.data.express.catalogGroupView
})
})
}
render() {
const { mainCategory } = this.state;
return mainCategory.map(navList => {
return (
<ul className="header">
<li key={navList.uniqueID}>
<a className="dropbtn ">{navList.name} </a>
<ul className="dropdown-content">
<SubMenu below={navList.catalogGroupView} />
</ul>
</li>
</ul>
)
})
}
}
export default Navigation;
subMenu.js
In the submenu.js, I have created one more component SubListMenu for displaying the inner categories like Shoes, Pants, Skirts, Tops etc.
import React, { Component } from 'react';
import SubListMenu from './subListMenu';
class SubMenu extends Component {
render() {
const { below } = this.props;
return below.map(sub => {
return (
<React.Fragment>
<li key={sub.uniqueID}>
<a>{sub.name}</a>
{
<ul className="sub-menu">
{sub.catalogGroupView !== undefined && <SubListMenu id={sub.uniqueID} subBelow={sub.catalogGroupView} />}
</ul>
}
</li>
</React.Fragment>
)
})
}
}
export default SubMenu;
subListMenu.js
import React, { Component } from 'react';
import {Link} from 'react-router-dom';
class SubListMenu extends Component {
render() {
const { subBelow, id } = this.props;
console.log(subBelow)
return(
<React.Fragment>
{subBelow && subBelow.map(subl => {
return (
<li key={subl.uniqueID}><Link to = {`Apparel/Girls/${subl.name}/${ subl.uniqueID }`}>{subl.name}</Link></li>
)
})
}
</React.Fragment>
)
}
}
export default SubListMenu;
As you can see from my subListMenu.js code, that I have set the Link to PLPMenu.js. But in my case it's not happening. Also, the part Apparel/Girls in the Link, I have hard coded which i'm not able to make it dynamic.
PLPMenu.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
class PLPMenu extends Component {
state = {
shoeCategory: []
}
componentDidMount() {
let pathname= this.props.match.params.id
console.log(pathname)
axios.get(`http://localhost:3030/${pathname}`)
.then(res => (res.json()))
.then(data => {
this.setState({
shoeCategory: data.express.catalogEntryView
})
});
}
render() {
const { shoeCategory } = this.state;
const picUrl = 'https://149.129.128.3:8443'
return (
<div>
<div className="container">
<div className="row">
{
shoeCategory && shoeCategory.map(shoeList => (
<div className="col-md-4">
<h2 key={shoeList.uniqueID}></h2>
<img src={picUrl + shoeList.thumbnail} />
<Link to="/PDP"><p className="pdp">{shoeList.name}</p></Link>
<p>Price : {shoeList.price[0].value} {shoeList.price[0].currency}</p>
</div>
))
}
</div>
</div>
</div>
)
}
}
export default PLPMenu;
For fetching the data, I have used a node server.
server.js
const express = require('express');
const cors = require('cors');
const Client = require('node-rest-client').Client;//import it here
const app = express();
app.use(cors());
app.get('/topCategory', (req, res) => {
var client = new Client();
// direct way
client.get("http://149.129.128.3:3737/search/resources/store/1/categoryview/#top?depthAndLimit=-1,-1,-1,-1", (data, response) => {
res.send({ express: data });
});
});
app.get('/GirlShoeCategory', (req, res) => {
var client = new Client();
// direct way
client.get("http://149.129.128.3:3737/search/resources/store/1/productview/byCategory/10015", (data, response) => {
res.send({ express: data });
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port${port}`));
I don't know where my code is getting wrong. Maybe I feel that from the node server, there is a mismatch with the reactjs routes, for which only in the url, it's displaying the link but not the contents. Can someone please give me an insight on this. My console browser window:
for this issue
In the PLPMenu.js page, I'm trying to fetch the data. But all I'm getting is this undefined.
componentDidMount() {
let pathname= this.props.match.params.id
console.log(this.props.match.params.id)
axios.get(`http://localhost:3030/${pathname}`)
.then(res => {return res.json();})
.then(data => {
this.setState({
shoeCategory: data.express.catalogEntryView
})
});
}
try this it will solve undefined issue.
I believe you have to take id from subBelow instead this.props.id.
so change the code like this.
<li key={subl.uniqueID}><Link to = {`Apparel/Girls/${ subl.uniqueID }`}>{subl.name}</Link></li>
The reason you get undefined in URL bar because you are not passing the unique id from SubMenu down to SubListMenu component.
What you need to do is
SubMenu.js
import React, { Component } from 'react';
import SubListMenu from './subListMenu';
class SubMenu extends Component {
render() {
const { below } = this.props;
return below.map(sub => {
return (
<React.Fragment>
<li key={sub.uniqueID}>
<a>{sub.name}</a>
{
<ul className="sub-menu">
{sub.catalogGroupView !== undefined && <SubListMenu id={sub.uniqueID} subBelow={sub.catalogGroupView} />}
</ul>
}
</li>
</React.Fragment>
)
})
}
}
export default SubMenu;
SubListMenus.js
import React, { Component } from 'react';
import {Link} from 'react-router-dom';
class SubListMenu extends Component {
render() {
const { subBelow, id } = this.props;
console.log(subBelow)
return(
<React.Fragment>
{subBelow && subBelow.map(subl => {
return (
<li key={subl.uniqueID}><Link to = {`Apparel/Girls/${ id }`}>{subl.name}</Link></li>
)
})
}
</React.Fragment>
)
}
}
export default SubListMenu;
Regarding below issue You need to do res.json() and in next .then get the data
In the PLPMenu.js page, I'm trying to fetch the data. But all I'm getting is this undefined.
Do this
componentDidMount() {
let pathname= this.props.match.params.id
console.log(this.props.match.params.id)
axios.get(`http://localhost:3030/${pathname}`)
.then(res => (res.json()))
.then(data => {
this.setState({
shoeCategory: data.express.catalogEntryView
})
});
}
Edit:
Add below condition in PLPMenu component
{shoeCategory && shoeCategory.map(shoeList => (
I have a React component which is GaleryPage and i want to show a list of information i found them with my Back end side which are file_name and Type_contract .This is my back End side code :
app.post('/convert', upload.single('file'),(req, res) =>{
if(req.file){
let file= req.file.filename
let Type_contract = 'Contract'
let file_name = path.basename(file,path.extname(file))
console.log(file_name);
console.log(Type_contract);
}
res.redirect('/');
and here is my React component :
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
class GaleryPage extends Component {
constructor(props) {
super(props);
this.state = {
file_name: '',
Type_contract:''
};
}
componentDidMount() {
const data = new FormData();
fetch('http://localhost:8080/upload',{
method: 'POST',
body: data
})
.then((file_name,Type_contract) => this.setState({
file_name: file_name,
Type_contract:Type_contract
})
)}
render() {
return (
<div>
<ul>
<li file_name={this.state.file_name}>file_name=
{this.state.file_name}</li>
<li Type_contract={this.state.Type_contract}>Type_contract=
{this.state.Type_contract}</li>
</ul>
</div>
);
}
}
export default GaleryPage;
when i try this code i find always empty page and no data is not showning