./src/components/BookDetails/bookdetails.jsx 147:14
Module parse failed: Unexpected token (147:14)
You may need an appropriate loader to handle this file type.
| }
| }, /*#__PURE__*/React.createElement("img", {
> src: book?.cover_img,
| alt: "cover img",
| __self: _this,
Hi everyone! I've tried googling this issue, modifying my webpack.config.js file, modifying the "babel", removed node modules & package-lock.json & re-install npm but I keep getting this error.
I think the "?" right after the "book" might be triggering the error, I'm not sure. Any help would be great!!!
The entire code for this is here:
import React, {useState, useEffect} from 'react';
import { useParams } from 'react-router-dom';
import Loading from "../Loader/loader";
import coverImg from "../../images/notfound.jpg";
import "./bookdetails.css";
import {FaArrowLeft} from "react-icons/fa";
import { useNavigate } from 'react-router-dom';
const URL = "https://openlibrary.org/works/";
const Bookdetails = () => {
const {id} = useParams();
const [loading, setLoading] = useState(false);
const [book, setBook] = useState(null);
const navigate = useNavigate();
useEffect(() => {
setLoading(true);
async function getBookDetails(){
try{
const response = await fetch(`${URL}${id}.json`);
const data = await response.json();
if(data){
const {description, title, covers, subject_places, subject_times, subjects} = data;
const newBook = {
description: description ? description.value : "No description found",
title: title,
cover_img: covers ? `https://covers.openlibrary.org/b/id/${covers[0]}-L.jpg` : coverImg,
subject_places: subject_places ? subject_places.join(", ") : "No subject places found",
subject_times: subject_times ? subject_times.join(", ") : "No subject times found",
subjects: subjects ? subjects.join(", ") : "No subjects found"
};
setBook(newBook);
} else{
setBook(null);
}
setLoading(false);
} catch(error){
console.log(error);
setLoading(false);
}
}
getBookDetails();
}, [id]);
if (loading) return <Loading/>;
return (
<section className='book-details'>
<div className='container'>
<button type='button' className='flex flex-c back-btn' onClick={() => navigate("/book")}>
<FaArrowLeft size = {22} />
<span className='fs-18 fw-6'>Go back</span>
</button>
<div className='book-details-content grid'>
<div className='book-details-img'>
<img src = {book?.cover_img} alt = "cover img"/>
</div>
<div className='book-details-info'>
<div className='book-details-item title'>
<span className='fw-6 fs-24'>{book.title}</span>
</div>
<div className='book-details-item description'>
<span>{book?.description}</span>
</div>
<div className='book-details-item'>
<span className='fw-6'>Subject Places: </span>
<span className='text-italic'>{book?.subject_places}</span>
</div>
<div className='book-details-item'>
<span className='fw-6'>Subject Times: </span>
<span className='text-italic'>{book?.subject_times}</span>
</div>
<div className='book-details-item'>
<span className='fw-6'>Subjects : </span>
<span>{book?.subjects}</span>
</div>
</div>
</div>
</div>
</section>
)
}
export default Bookdetails
And my package.json looks like this:
{
"name": "book-app",
"version": "0.1.0",
"private": true,
"resolutions": {
"acorn": "8.0.1"
},
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"file-loader": "^6.2.0",
"npm-force-resolutions": "^0.0.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.7.1",
"react-router-dom": "^6.8.1",
"react-scripts": "^2.1.3",
"url-loader": "^4.1.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
"build": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"preinstall": "npx npm-force-resolutions"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Related
I have a React App(v18.2.0) with react-router-dom(v5.2.0). The navigation works correctly but when I click the browser's Back button the URL changes but no state is updated and the page doesn't get re-rendered. I tried so many different things and none of them works.
A case for example, is when I call the CreateUserComponent on the ListUserComponent, then if i want to go backwards using the browser back button the URL changes to the List component but the screen keeps the same.
So my question is how can I get the page to load when the user goes back, because i do not know what i am doing wrong?
App.js
import React from 'react';
import './App.css';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import ListUserComponent from './components/ListUserComponent';
import HeaderComponent from './components/HeaderComponent';
import FooterComponent from './components/FooterComponent';
import CreateUserComponent from './components/CreateUserComponent';
import UpdateUserComponent from './components/UpdateUserComponent';
import ViewUserComponent from './components/ViewUserComponent';
function App() {
return (
<div>
<Router forceRefresh={true}>
<HeaderComponent />
<div className="container">
<Switch>
<Route path = "/" exact component = {ListUserComponent}></Route>
<Route path = "/users" component = {ListUserComponent}></Route>
<Route path = "/add-user/:id" component = {CreateUserComponent}></Route>
<Route path = "/view-user/:id" component = {ViewUserComponent}></Route>
</Switch>
</div>
<FooterComponent />
</Router>
</div>
);
}
export default App;
CreateUserComponent.jsx
import React, { Component } from 'react';
import UserService from '../services/UserService';
class CreateUserComponent extends Component {
constructor(props) {
super(props)
this.state = {
//Step 2
id: this.props.match.params.id,
firstName: '',
lastName: '',
email: '',
password: ''
}
this.changeFirstNameHandler = this.changeFirstNameHandler.bind(this);
this.changeLastNameHandler = this.changeLastNameHandler.bind(this);
this.saveOrUpdateUser = this.saveOrUpdateUser.bind(this);
}
//Step 3
componentDidMount() {
//Step 4
if (this.state.id === 'add') {
return
} else {
UserService.getUserById(this.state.id).then((res) => {
let user = res.data;
this.setState({
firstName: user.firstName,
lastName: user.lastName,
emailId: user.emailId
});
});
}
}
saveOrUpdateUser = (e) => {
e.preventDefault();
let user = { firstName: this.state.firstName, lastName: this.state.lastName, email: this.state.email, password: this.state.password };
console.log('user => ' + JSON.stringify(user));
//Step 5
if (this.state.id === 'add') {
UserService.createUser(user).then(res => {
this.props.history.push('/users');
});
} else {
UserService.updateUser(user, this.state.id).then(res => {
this.props.history.push('/users');
});
}
}
changeFirstNameHandler = (event) => {
this.setState({ firstName: event.target.value });
}
changeLastNameHandler = (event) => {
this.setState({ lastName: event.target.value });
}
changeEmailHandler = (event) => {
this.setState({ email: event.target.value });
}
changePasswordHandler = (event) => {
this.setState({ password: event.target.value });
}
cancel() {
this.props.history.push('/users');
}
getTitle() {
if (this.state.id === 'add') {
return <h3 className="text-center">Modificar Usuario</h3>
} else {
return <h3 className="text-center">Añadir Usuario</h3>
}
}
render() {
return (
<div>
<div className="container">
<div className="row">
<div className="card col-md-6 offset-md-3 offset-md-3">
{
this.getTitle()
}
<div className="card-body">
<form>
<div className="form-group">
<label>Nombre: </label>
<input placeholder="Nombre" name="firstName" className="form-control" value={this.state.firstName} onChange={this.changeFirstNameHandler} />
</div>
<div className="form-group">
<label> Apellidos: </label>
<input placeholder="Apellidos" name="lastName" className="form-control" value={this.state.lastName} onChange={this.changeLastNameHandler} />
</div>
<div className="form-group">
<label> Email: </label>
<input placeholder="Email" name="email" className="form-control" value={this.state.email} onChange={this.changeEmailHandler} />
</div>
<div className="form-group">
<label> Contraseña: </label>
<input placeholder="Contraseña" name="password" className="form-control" value={this.state.password} onChange={this.changePasswordHandler} />
</div>
<button className="btn btn-success" onClick={this.saveOrUpdateUser}>Guardar</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{ marginLeft: "10px" }}>Cancelar</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CreateUserComponent;
package.json
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"axios": "^1.1.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Your components work well on my machine since I've added preventDefault() to the cancel function.
App.jsx
import React from 'react';
import './App.css';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import ListUserComponent from './components/ListUserComponent';
import HeaderComponent from './components/HeaderComponent';
import FooterComponent from './components/FooterComponent';
import CreateUserComponent from './components/CreateUserComponent';
import UpdateUserComponent from './components/UpdateUserComponent';
import ViewUserComponent from './components/ViewUserComponent';
function App() {
return (
<div>
<Router> {/* removed forceRefresh */}
<HeaderComponent />
<div className="container">
<Switch>
<Route path = "/" exact component = {ListUserComponent}></Route>
<Route path = "/users" component = {ListUserComponent}></Route>
<Route path = "/add-user/:id" component = {CreateUserComponent}></Route>
<Route path = "/view-user/:id" component = {ViewUserComponent}></Route>
</Switch>
</div>
<FooterComponent />
</Router>
</div>
);
}
export default App;
CreateUserComponent.jsx
import React, { Component } from 'react';
// import UserService from '../services/UserService';
class CreateUserComponent extends Component {
constructor(props) {
super(props)
this.state = {
//Step 2
id: this.props.match.params.id,
firstName: '',
lastName: '',
email: '',
password: ''
}
this.changeFirstNameHandler = this.changeFirstNameHandler.bind(this);
this.changeLastNameHandler = this.changeLastNameHandler.bind(this);
this.saveOrUpdateUser = this.saveOrUpdateUser.bind(this);
}
//Step 3
componentDidMount() {
//Step 4
if (this.state.id === 'add') {
return
} else {
// UserService.getUserById(this.state.id).then((res) => {
// let user = res.data;
// this.setState({
// firstName: user.firstName,
// lastName: user.lastName,
// emailId: user.emailId
// });
// });
}
}
saveOrUpdateUser = (e) => {
e.preventDefault();
let user = { firstName: this.state.firstName, lastName: this.state.lastName, email: this.state.email, password: this.state.password };
console.log('user => ' + JSON.stringify(user));
//Step 5
if (this.state.id === 'add') {
// UserService.createUser(user).then(res => {
// this.props.history.push('/users');
// });
} else {
// UserService.updateUser(user, this.state.id).then(res => {
// this.props.history.push('/users');
// });
}
}
changeFirstNameHandler = (event) => {
this.setState({ firstName: event.target.value });
}
changeLastNameHandler = (event) => {
this.setState({ lastName: event.target.value });
}
changeEmailHandler = (event) => {
this.setState({ email: event.target.value });
}
changePasswordHandler = (event) => {
this.setState({ password: event.target.value });
}
cancel(event) {
event.preventDefault(); // added preventDefault()
this.props.history.push('/users');
}
getTitle() {
if (this.state.id === 'add') {
return <h3 className="text-center">Modificar Usuario</h3>
} else {
return <h3 className="text-center">Añadir Usuario</h3>
}
}
render() {
return (
<div>
<div className="container">
<div className="row">
<div className="card col-md-6 offset-md-3 offset-md-3">
{
this.getTitle()
}
<div className="card-body">
<form>
<div className="form-group">
<label>Nombre: </label>
<input placeholder="Nombre" name="firstName" className="form-control" value={this.state.firstName} onChange={this.changeFirstNameHandler} />
</div>
<div className="form-group">
<label> Apellidos: </label>
<input placeholder="Apellidos" name="lastName" className="form-control" value={this.state.lastName} onChange={this.changeLastNameHandler} />
</div>
<div className="form-group">
<label> Email: </label>
<input placeholder="Email" name="email" className="form-control" value={this.state.email} onChange={this.changeEmailHandler} />
</div>
<div className="form-group">
<label> Contraseña: </label>
<input placeholder="Contraseña" name="password" className="form-control" value={this.state.password} onChange={this.changePasswordHandler} />
</div>
<button className="btn btn-success" onClick={this.saveOrUpdateUser}>Guardar</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{ marginLeft: "10px" }}>Cancelar</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CreateUserComponent;
If it doesn't work please share the snippets that show how you've come to /add-user/add like onClick of Header Link or Add button in ListUserComponent.
I guess this is because of cache
The browser caches the entire page for the browser performance
You might have noticed that when to visit a new page the action takes much time and if you press back (chrome back button) the page views fast
That is why there is no state change in the app and your component will not re-render
You should block chrome back button or use useRouter for previous page
If you go back, it's normal that it use cache instead of reload.
HERE IS THE REACT CODE
import React, { useEffect, useState } from "react";
import "./css/style.css";
import { BiStreetView } from "react-icons/bi";
const Tempapp = () => {
const [city, setCity] = useState(null);
const [search, setSearch] = useState("");
useEffect(() => {
try {
const fetchApi = async () => {
const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=83ea3057047027c6c4521d32d69250a0`;
const res = await fetch(url);
const resjson = await res.json();
setCity(resjson);
};
fetchApi();
} catch (error) {
console.log(error);
}
}, [search]);
return (
<>
<div className="box">
<div className="inputData">
<input
type="search"
className="inputFeild"
value={search}
placeholder="Enter city"
onChange={(event) => {
setSearch(event.target.value);
}}
/>
</div>
{!city ? (
<p>Enter city or country to know weather</p>
) : (
<div>
<div className="info">
<img
src="../images/weather.png"
alt="image"
className="info-img"
/>
<h3 className="dateTime">{date}</h3>
<h3 className="dateTime">{time}</h3>
<h2 className="location">
<BiStreetView className="location-icon" />
{search}
</h2>
<h1 className="temp">{city.main.temp} °Cel</h1>
<h3 className="tempmin_max">
Min : {city.main.temp_min} °Cel | Max : {city.main.temp_max} °Cel
</h3>
</div>
<div className="wave -one"></div>
<div className="wave -two"></div>
<div className="wave -three"></div>
</div>
)}
</div>
</>
);
};
export default Tempapp;
AND HERE IS THE API DATA. AND I WANT TO USE THE MAIN PART AND WEATHER PART OF DATA.
and I want to get the temperature, temp_min, temp_max from main object and main from the weather array. I am getting error called cannot read property of undefined reading "temp".
please someone solve this.
{
"coord": {
"lon": 73.8333,
"lat": 15.4833
},
"weather": [{
"id": 804,
"main": "Clouds",
"description": "overcast clouds",
"icon": "04n"
}],
"base": "stations",
"main": {
"temp": 298.95,
"feels_like": 299.75,
"temp_min": 298.95,
"temp_max": 298.95,
"pressure": 1011,
"humidity": 83,
"sea_level": 1011,
"grnd_level": 1011
},
"visibility": 10000,
"wind": {
"speed": 2.94,
"deg": 303,
"gust": 4.1
},
"clouds": {
"all": 86
},
"dt": 1663596174,
"sys": {
"country": "IN",
"sunrise": 1663548808,
"sunset": 1663592632
},
"timezone": 19800,
"id": 1260607,
"name": "Panjim",
"cod": 200
}
Below is the working version of your app. Try using optional chaining for your async datas while reading them. Plus, you should consider why you need useEffect which has search dependency that rerenders your component.
import React, { useEffect, useState } from 'react';
const Tempapp = () => {
const [city, setCity] = useState('');
const [search, setSearch] = useState('');
const fetchApi = async () => {
try {
const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=83ea3057047027c6c4521d32d69250a0`;
const res = await fetch(url);
const data = await res.json();
setCity(data);
} catch (error) {
console.log(error);
}
};
const handleSubmit = (e) => {
e.preventDefault();
fetchApi();
};
return (
<>
<div className="box">
<form onSubmit={handleSubmit} className="inputData">
<input
type="search"
className="inputFeild"
value={search}
placeholder="Enter city"
onChange={(event) => {
setSearch(event.target.value);
}}
/>
<button type="submit">Search</button>
</form>
{!city ? (
<p>Enter city or country to know weather</p>
) : (
<div>
<div className="info">
<img
src="../images/weather.png"
alt="image"
className="info-img"
/>
<h1 className="temp">{city?.main?.temp} °Cel</h1>
<h3 className="tempmin_max">
Min : {city.main?.temp_min} °Cel | Max : {city.main?.temp_max}{' '}
°Cel
</h3>
</div>
<div className="wave -one"></div>
<div className="wave -two"></div>
<div className="wave -three"></div>
</div>
)}
</div>
</>
);
};
export default Tempapp;
import { useEffect, useState } from "react";
import Box from "#mui/material/Box";
import FormControl from "#mui/material/FormControl";
import InputLabel from "#mui/material/InputLabel";
import MenuItem from "#mui/material/MenuItem";
import Select from "#mui/material/Select";
const DropdownList = (props) => {
const [course, setCourse] = useState("");
const handleChange = (event) => {
setCourse(event.target.value);
// props.onSelectedCourse(event.target.value);
};
return (
<div>
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="inputId">Select Courses</InputLabel>
<Select
id="demo-simple-select"
labelId="inputId"
value={course}
label="Select Courses"
onChange={handleChange}
>
{props.content.df?.map((name) => {
<MenuItem value={name.course}>{name.course}</MenuItem>;
})}
</Select>
</FormControl>
</Box>
</div>
);
};
export default DropdownList;
I am trying to display dynamic data into react MUI dropdown list. However, no data is shown in the dropdown list. The props passed to the DropdownList component is from a smart component name DropdownSmart which gets the HTTP request as shown below.
import React, { useEffect, useState } from "react";
import DropdownList from "../components/dropdown/DropdownList";
import axios from "axios";
const DropdownSmart = () => {
const [content, setContents] = useState({});
useEffect(() => {
axios.get("http://localhost:5000/getCourses").then((res) => {
// let a = res.data.df;
// setContents(a);
console.log(res.data);
setContents(res.data);
});
}, []);
return <DropdownList content={content}></DropdownList>;
};
export default DropdownSmart;
The data get from the http request is in JSON format as shown below
{
"df": [
{
"course": "Data Warehouse Fundamentals"
},
{
"course": "Hadoop"
},
{
"course": "Java"
},
{
"course": "Linux"
},
{
"course": "On-Job Project 1"
},
{
"course": "On-Job Project 2"
},
{
"course": "Python Basics"
},
{
"course": "Python OOPS"
},
{
"course": "Soft Skills Upskilling"
}
]
}
The issue is that nothing is shown in the dropdown list. Would really appreciate it if anyone could help a newbie out here. Thanks in advance!
You are not returning anything from inside map which is explicit return and it returns undefined as a result
You can read this blog - Implicit & Explicit return in JS
{props.content.df?.map((name) => {
return <MenuItem value={name.course}>{name.course}</MenuItem>; //here
})}
or just do implicit return as below (just by removing the braces and replacing with paranthesis 😉)
{props.content.df?.map((name) => (
<MenuItem value={name.course}>{name.course}</MenuItem>;
))}
I seem to have a problem on my React Frontend I am working on my Reset.js page and I keep getting an error as
TypeError: Cannot read property 'params' of undefined
It happens as soon as I route to the Reset.js page and how this was working is that when a User forgets their password they are sent an email in order to Reset their password using jwt and when the link is clicked on the email it would route you to the Reset.js page and this is where you will fill in credentials to reset your password.
But in the process when the route is reached I get a TypeError: Cannot read property 'params' of undefined Error and this is the affected React js line of code shown below.
14 | const { password1, password2, textChange, token } = formData;
15 |
16 | useEffect(() => {
> 17 | let token = match.params.token // **Error is caused here Cannot read property 'params' of undefined**
| ^ 18 | if(token) {
19 | setFormData({...formData, token,})
20 | }
This is also a screenshot to the Chrome Error for easy viewing.
And here is the full code for my Reset.js page in React.
import React, { useState, useEffect } from 'react';
import authSvg from '../assets/reset.svg';
import { ToastContainer, toast } from 'react-toastify';
import axios from 'axios';
const Reset = ({match}) => {
const [formData, setFormData] = useState({
password1: '',
password2: '',
token: '',
textChange: 'Submit'
});
// eslint-disable-next-line no-unused-vars
const { password1, password2, textChange, token } = formData;
useEffect(() => {
let token = match.params.token // **Error is caused here Cannot read property 'params' of undefined**
if(token) {
setFormData({...formData, token,})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const handleChange = text => e => {
setFormData({ ...formData, [text]: e.target.value });
};
const handleSubmit = e => {
console.log(password1, password2)
e.preventDefault();
if ((password1 === password2) && password1 && password2) {
setFormData({ ...formData, textChange: 'Submitting' });
axios
.put(`${process.env.REACT_APP_API_URL}/password/reset`, {
newPassword: password1,
resetPasswordLink: token
})
.then(res => {
console.log(res.data.message)
setFormData({
...formData,
password1: '',
password2: ''
});
toast.success(res.data.message);
})
.catch(err => {
toast.error('Something is wrong try again');
});
} else {
toast.error('Passwords don\'t matches');
}
};
return (
<div className='min-h-screen bg-gray-100 text-gray-900 flex justify-center'>
<ToastContainer />
<div className='max-w-screen-xl m-0 sm:m-20 bg-white shadow sm:rounded-lg flex justify-center flex-1'>
<div className='lg:w-1/2 xl:w-5/12 p-6 sm:p-12'>
<div className='mt-12 flex flex-col items-center'>
<h1 className='text-2xl xl:text-3xl font-extrabold'>
Reset Your Password
</h1>
<div className='w-full flex-1 mt-8 text-indigo-500'>
<form
className='mx-auto max-w-xs relative '
onSubmit={handleSubmit}
>
<input
className='w-full px-8 py-4 rounded-lg font-medium bg-gray-100 border border-gray-200 placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white'
type='password'
placeholder='password'
onChange={handleChange('password1')}
value={password1}
/>
<input
className='w-full mt-5 px-8 py-4 rounded-lg font-medium bg-gray-100 border border-gray-200 placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white'
type='password'
placeholder='Confirm password'
onChange={handleChange('password2')}
value={password2}
/>
<button
type='submit'
className='mt-5 tracking-wide font-semibold bg-indigo-500 text-gray-100 w-full py-4 rounded-lg hover:bg-indigo-700 transition-all duration-300 ease-in-out flex items-center justify-center focus:shadow-outline focus:outline-none'
>
<i className='fas fa-sign-in-alt w-6 -ml-2' />
<span className='ml-3'>Submit</span>
</button>
</form>
</div>
</div>
</div>
<div className='flex-1 bg-indigo-100 text-center hidden lg:flex'>
<div
className='m-12 xl:m-16 w-full bg-contain bg-center bg-no-repeat'
style={{ backgroundImage: `url(${authSvg})` }}
></div>
</div>
</div>
;
</div>
);
};
export default Reset;
I also tried to fix it by adding useParams though it didn't seem to workout as planned but this is the fix I tried making and didn't workout so I decided to reach out for some help,
This is what I had tried out below;
import { useParams } from 'react-router-dom';
import jwt from 'jsonwebtoken'; //added this because of the way I was using jwt.decode
textChange: 'Submit'
});
// eslint-disable-next-line no-unused-vars
const { password1, password2, textChange } = formData; //I removed token from here since we were calling it on line 21 in the params below
// const { password1, password2, textChange, token } = formData; //this is the original code format and the one above is what I edited.
const { token } = useParams();
useEffect(() => {
let password = jwt.decode(token); //added jwt.decode(token) here though at first it was match.params.token
// let token = match.params.token
if(token) {
setFormData({...formData,password, token,}) //added password here tho it wasnt supposed to be their as reference to the original code.
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
The Error Displayed when I tried out the above code with useParams read as in the Chrome console.
PUT http://localhost:4000/api/password/reset 400 (Bad Request)
Below is the Error but in a Screenshot form for easy viewing but its the same as the one above.
And then below are the routes i was using for my Reset.js Page
import { Navigate } from 'react-router-dom';
import DashboardLayout from 'src/components/DashboardLayout';
import MainLayout from 'src/components/MainLayout';
import Account from 'src/pages/Account';
import CustomerList from 'src/pages/CustomerList';
import AssistantList from 'src/pages/AssistantList';
import MarketList from 'src/pages/MarketList';
import Dashboard from 'src/pages/Dashboard';
import Login from 'src/pages/Login';
import NotFound from 'src/pages/NotFound';
import ProductList from 'src/pages/ProductList';
import Register from 'src/pages/Register';
import Settings from 'src/pages/Settings';
import Activate from 'src/pages/Activate';
import Forget from 'src/pages/Forget';
import Reset from 'src/pages/Reset'; //This is how I imported my Reset.js Page
const routes = [
{
path: 'app',
element: <DashboardLayout />,
children: [
{ path: 'account', element: <Account /> },
{ path: 'assistants', element: <AssistantList /> },
{ path: 'customers', element: <CustomerList /> },
{ path: 'dashboard', element: <Dashboard /> },
{ path: 'markets', element: <MarketList /> },
{ path: 'products', element: <ProductList /> },
{ path: 'settings', element: <Settings /> },
{ path: '*', element: <Navigate to="/404" /> }
]
},
{
path: '/',
element: <MainLayout />,
children: [
{ path: 'login', element: <Login /> },
{ path: 'register', element: <Register /> },
{ path: '404', element: <NotFound /> },
{ path: '/', element: <Navigate to="/app/dashboard" /> },
{ path: '*', element: <Navigate to="/404" /> },
{ path: '/users/activate/:token', element: <Activate /> },
{ path: '/users/password/forget', element: <Forget /> },
{ path: '/users/password/reset/:token', element: <Reset /> } //Here is how I routed my reset.js page
]
}
];
export default routes;
Wrap your Reset component with withRouter (https://reactrouter.com/web/api/withRouter)
I want to increase the likes of a single blog by 1 in the incLikes function and put the updated blog back in the blogs state
const App = () => {
const [ blogs, setBlogs ] = useState(null)
useEffect(() => {
blogsService.getAll().then(initialBlogs => {
setBlogs(initialBlogs)
})
}, [])
const incLikes = blog => {
...
}
...
My mongo database contains the following blogs:
[
{
"title": "The lost planet in the milky way",
"author": "Ford Beeblebrox",
"url": "www.goldenplanet.milky.way",
"likes": 102,
"id": "600aabcbf4492017c4068727"
},
{
"title": "How the Vogols destroyed the Earth",
"author": "Michael Faraday",
"url": "www.far-far-aday.com",
"likes": 45,
"id": "600ab1575883720a04743319"
}
]
To give you a fuller context, here is how you would do it:
const [blogs, setBlogs] = React.useState(all_blogs);
const incLikes = (blog) => {
setBlogs(
blogs.map((b) => {
if (b.id === blog.id) b.likes++;
return b;
})
);
};
return (
<div className="App">
<h1>Blogs:</h1>
{blogs.map((item, i) => (
<div key={i}>
{item.title} (Likes: {item.likes}) --{" "}
<button onClick={() => incLikes(item)}> Like</button>
</div>
))}
</div>
);
So the idea is to pass a blog object into your function, then map through all the blog objects stored in the state and increment the matching one. Here is a sandbox for you.