How to pass data between pages in react when using useparams()? [duplicate] - javascript

This question already has answers here:
How to pass data from a page to another page using react router
(5 answers)
Closed 7 days ago.
App.jsx
import './App.css'
import React, {useState} from 'react';
import { Link, Routes, Route } from 'react-router-dom';
import Calendar from "./components/calendar/calendar.jsx";
import ToDo from "./components/todolist/todolist.jsx";
import { useParams } from 'react-router-dom';
const App = () => {
return (
<div>
<Routes>
<Route path='/' element={<Calendar />} />
<Route path='/todo/:id' element={<ToDo />} />
</Routes>
</div>
)
}
export default App;
calendar.jsx
import './calendar.css'
import {Link} from 'react-router-dom'
import React from "react";
const Calendar = () => {
return (
<div className="month">
<h1> February 2023 </h1>
<div className="names">
<div className="weekNames">Monday</div>
<div className="weekNames">Tuesday</div>
<div className="weekNames">Wednesday</div>
<div className="weekNames">Thursday</div>
<div className="weekNames">Friday</div>
<div className="weekNames">Saturday</div>
<div className="weekNames">Sunday</div>
</div>
<div className="week">
<div className="day">1 <Link to='/todo/1'> To-Do: </Link> </div>
<div className="day">2 <Link to='/todo/2'> To-Do: </Link> </div>
<div className="day">3 <Link to='/todo/3'> To-Do: </Link> </div>
<div className="day">4 <Link to='/todo/4'> To-Do: </Link> </div>
<div className="day">5 <Link to='/todo/5'> To-Do: </Link> </div>
<div className="day">6 <Link to='/todo/6'> To-Do: </Link> </div>
<div className="day">7 <Link to='/todo/7'> To-Do: </Link> </div>
<div className="day">8 <Link to='/todo/8'> To-Do: </Link></div>
<div className="day">9 <Link to='/todo/9'> To-Do: </Link> </div>
<div className="day">10 <Link to='/todo/10'> To-Do: </Link> </div>
<div className="day">11 <Link to='/todo/11'> To-Do: </Link> </div>
<div className="day">12 <Link to='/todo/12'> To-Do: </Link> </div>
<div className="day">13 <Link to='/todo/13'> To-Do: </Link> </div>
<div className="day">14 <Link to='/todo/14'> To-Do: </Link> </div>
<div className="day">15 <Link to='/todo/15'> To-Do: </Link> </div>
<div className="day">16 <Link to='/todo/16'> To-Do: </Link> </div>
<div className="day">17 <Link to='/todo/17'> To-Do: </Link> </div>
<div className="day">18 <Link to='/todo/18'> To-Do: </Link> </div>
<div className="day">19 <Link to='/todo/19'> To-Do: </Link> </div>
<div className="day">20 <Link to='/todo/20'> To-Do: </Link> </div>
<div className="day">21 <Link to='/todo/21'> To-Do: </Link> </div>
<div className="day">22 <Link to='/todo/22'> To-Do: </Link> </div>
<div className="day">23 <Link to='/todo/23'> To-Do: </Link> </div>
<div className="day">24 <Link to='/todo/24'> To-Do: </Link> </div>
<div className="day">25 <Link to='/todo/25'> To-Do: </Link> </div>
<div className="day">26 <Link to='/todo/26'> To-Do: </Link> </div>
<div className="day">27 <Link to='/todo/27'> To-Do: </Link> </div>
<div className="day">28 <Link to='/todo/28'> To-Do: </Link> </div>
</div>
</div>
);
}
export default Calendar
todolist.jsx
import './todolist.css'
import React from "react";
import { NavLink } from "react-router-dom";
import { useParams } from 'react-router-dom';
const ToDo = () => {
const {id} = useParams()
const [todos, setTodos] = React.useState(() => JSON.parse(localStorage.getItem(`todos-${id}`)) || []);
const [todo, setTodo] = React.useState("");
const [todoEditing, setTodoEditing] = React.useState(null);
const [editingText, setEditingText] = React.useState("");
React.useEffect(() => {
const json = JSON.stringify(todos);
localStorage.setItem(`todos-${id}`, json);
}, [todos, id]);
function handleSubmit(e) {
e.preventDefault();
const newTodo = {
id: new Date().getTime(),
text: todo,
completed: false,
};
setTodos([...todos].concat(newTodo));
setTodo("");
}
function deleteTodo(id) {
let updatedTodos = [...todos].filter((todo) => todo.id !== id);
setTodos(updatedTodos);
}
function toggleComplete(id) {
let updatedTodos = [...todos].map((todo) => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
setTodos(updatedTodos);
}
function submitEdits(id) {
const updatedTodos = [...todos].map((todo) => {
if (todo.id === id) {
todo.text = editingText;
}
return todo;
});
setTodos(updatedTodos);
setTodoEditing(null);
}
return (
<div>
<div align='right'>
<NavLink to='/' style={{textDecoration: 'none', color: 'black'}}><button className='btn'> Calendar View </button></NavLink>
</div>
<div id="todo-list">
<h1>To-Do For Today</h1>
<h2> Total Tasks: {todos.length} </h2>
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={(e) => setTodo(e.target.value)}
value={todo}
/>
<button className="btn">Add To-Do</button>
</form>
{todos.map((todo) => (
<div key={todo.id} className="todo">
<div className="todo-text">
<input
type="checkbox"
id="completed"
checked={todo.completed}
onChange={() => toggleComplete(todo.id)}
/>
{todo.id === todoEditing ? (
<input
type="text"
onChange={(e) => setEditingText(e.target.value)}
/>
) : (
<div>{todo.text}</div>
)}
</div>
<div className="todo-actions">
{todo.id === todoEditing ? (
<button className='btnXS' onClick={() => submitEdits(todo.id)}>Submit</button>
) : (
<button className='btnXS' onClick={() => setTodoEditing(todo.id)}>Edit</button>
)}
<button className='btnXS' onClick={() => deleteTodo(todo.id)}>Delete</button>
</div>
</div>
))}
</div>
</div>
);
};
export default ToDo;
I am trying to built a calendar web app with daily to-do lists. So when clicking on the link on any day, the user should be able to add and edit what to do for that day. But I would also like to show the total number of todos added for each day in the calendar page. E.g. 1 To-Do: "show total numbers of to-dos for this day"
I tried calling {todos.length} on the calendar page, but it always shows 0.

I edit your Calendar.jsx and add new Day Component :
import './calendar.css'
import {Link} from 'react-router-dom'
import React from "react";
const Calendar = () => {
return (
<div className="month">
<h1> February 2023 </h1>
<div className="names">
<div className="weekNames">Monday</div>
<div className="weekNames">Tuesday</div>
<div className="weekNames">Wednesday</div>
<div className="weekNames">Thursday</div>
<div className="weekNames">Friday</div>
<div className="weekNames">Saturday</div>
<div className="weekNames">Sunday</div>
</div>
<div className="week">
<Day number={1} />
<Day number={2} />
<Day number={3} />
<Day number={4} />
<Day number={5} />
<Day number={6} />
<Day number={7} />
</div>
</div>
);
}
function Day({number}){
const [todos, setTodos] = React.useState(() => JSON.parse(localStorage.getItem(`todos-${id}`)) || []);
return (<div className="day">{number} <Link to={`/todo/${number}`}> To-Do: {todos.length} </Link> </div>);
}
export default Calendar;
Is that what you meant?

Related

How do I use useRef to Open ActionSheet with Details

I am having a single fruit with a list of infestations that I'm mapping on my react component. I want to open an ActionSheet with the details of an individual infestation when it is clicked. I have tried this way but its not working. Anyone, please help.
import React, { useState, useEffect, useRef } from "react";
import { Link, useNavigate, useParams } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar";
import Tabs from "../../components/fruittabs/FruitTabs";
import WidgetSkeleton from "../../components/skeleton/WidgetSkeleton"
import Skeleton from "react-loading-skeleton";
import toast, { Toaster } from 'react-hot-toast';
import axios from 'axios';
import InfestationWidget from "../../components/widgets/InfestationWidget"
import ActionSheet from "actionsheet-react";
import { LazyLoadImage } from "react-lazy-load-image-component";
function FruitDetails() {
let navigate = useNavigate();
const [fruit, setFruit] = useState({});
const { fruitId } = useParams();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
let isMounted = true;
axios.get(`/api/fruit/${fruitId}`).then(res => {
if (isMounted) {
if (res.data.status === 200) {
setFruit(res.data.fruit);
setIsLoading(false);
}
else if (res.data.status === 404) {
toast.error(res.data.message, "error");
}
}
});
return () => {
isMounted = false
};
}, []);
const ref = useRef(fruit.infestation && fruit.infestation.infestationid);
const handleOpen = () => {
ref.current.open();
console.log(`Fruit Infestation id: ${fruit.infestation.infestationid}`);
};
const handleClose = () => {
ref.current.close();
}
return (
<div>
<Menubar />
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-angle-left"></i>{" "}
</a>
</div>
<div className="pageTitle">{fruit.name}</div>
<div className="right"></div>
</div>
<Toaster />
<div id="appCapsule">
<div className="section mt-3 mb-3">
{isLoading ?
<Skeleton height={150} /> :
<LazyLoadImage
effect="blur"
width={'100%'}
src={`${process.env.REACT_APP_API_URL}/storage/fruits/${fruit.image}`}
alt="image"
className="imaged img-fluid fruit-detail-main"
/>}
</div>
<div className="section mt-3 mb-3">
<div>
<Tabs>
<div label="Details">
{isLoading && (
<Skeleton height={25} count="8" className="mb-05" />
)}
<div
dangerouslySetInnerHTML={{
__html: fruit.description,
}}
/>
</div>
<div label="Infestations">
<div className="mb-1">Here are some of the Popular Infestations for {fruit.name}</div>
<h3 className="mb-1">All Infestations</h3>
<div className="row">
{isLoading && <WidgetSkeleton cards={6} />}
{fruit.infestation && fruit.infestation.map((infestation) => (
<div className="col-6" infestation={infestation} key={infestation.infestationid}>
<div className="card mb-2">
<a onClick={handleOpen}>
<LazyLoadImage
src={`${process.env.REACT_APP_API_URL}/storage/infestations/${infestation.infestationimage}`}
className="card-img-top" alt="image" />
<div className="card-body card-bodysmall">
<p className="mb-0 text-sm-x">{infestation.infestationtype}</p>
<h4 className="mb-0">{infestation.infestationname}</h4>
</div>
</a>
</div>
</div>
))}
</div>
</div>
<div label="Advice">
<div
dangerouslySetInnerHTML={{
__html: fruit.advice,
}}
/>
</div>
</Tabs>
<ActionSheet
ref={ref}
sheetStyle={{
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
height: '80%'
}}>
<div className="bar" />
//Single Fruit Infestation Details
</ActionSheet>
</div>
</div>
</div>
</div>
);
}
export default FruitDetails;

updating my app and sidebar at the sametime using Usestate or Context API

function App() {
const [people, setPeople] = useState([
{
name: "Model Baby",
url:"https://www.themodelskit.co.uk/wp-
content/uploads/2021/10/shutterstock_1431963185.jpg"
},
{
name: "Seema Jaswal",
url:"https://static.standard.co.uk/2021/06/14/16/euro_2020_live_seema_jaswal_01-1.jpg?
width=968&auto=webp&quality=50&crop=968%3A645%2Csmart"
},
{
name: 'Plaboi Baby',
url: '../assets/IMG_20210811_105110_849.webp'
}
]);
const [per, setPer] = useState(people.name);
return (
<div className="app">
I am try to update my sidebar from the data above, i am trying to track changes in my sidebar from the main app, how do i effectively deploy useState or context API for this purpose
<Routes>
<Route path='/explore' element={<>
<div className='app__tinder'>
<TinderCards people={people} setPer={setPer} />
<SwipeButtons />
</div>
<aside className='app__sidebar right'>
<RightSidebar per={per} />
</aside>
</div>
</div>
</>} />
</div>
);
}
export default App;
TinderCard.js i need the name and age here to update on the sidebar when it changes
function TinderCards({people, setPer}) {
return (
<div>
<div className='tinderCards__cardContainer'>
{people.map((person) => (
<TinderCard className="swipe" key={person.name} preventSwipe={["up, down"]} onClick=
{() => {setPer(person.name)}} >
<div className='card' style={{ backgroundImage: `url(${person.url})`}}>
<h3>{person.name}</h3>
</div>
</TinderCard>
))}
</div>
</div>
)
}
export default TinderCards
RightSidebar, i tried applying useState but i am not sure that i am using it properly, pls help
function RightSidebar({per}) {
console.log("move", per)
return (
<div className='rightSidebar'>
{/* {people.map((person) => ( */}
<div className='rightSidebar__contents'>
<h1>About</h1>
<Card className='rightSidebar__card'>
<div className='card__nameContents'>
<CardHeader className='card__nameAge' title = {per.name} subheader =
{per.age} avatar =
{<VerifiedIcon className='activeIcon verified' />} />
<CardHeader className='card__active' title = "active" avatar=
{<FiberManualRecordIcon className='activeIcon' />} />
</div>

React error : Invalid prop `class` supplied to React.Fragment

enter image description here
Hello, we are currently experiencing the following errors in React. I'm not sure what's wrong with this error and it's being sent out. I tried to cover it with a tag instead of a <React.Fragment>, but the error above keeps appearing on the screen.
I think you're saying the wrong value is in the wrong tag. but I think, not found a problem with my code.
What could be wrong? I ask for your help me.
I attach my code.
import React, { useEffect, Fragment } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Helmet } from "react-helmet";
import {
POST_DETAIL_LOADING_REQUEST,
POST_DELETE_REQUEST,
USER_LOADING_REQUEST,
} from "../../redux/types";
import { Button, Row, Col } from "reactstrap";
import { Link } from "react-router-dom";
import CKEditor from "#ckeditor/ckeditor5-react";
import GrowingSpinner from "../../components/spinner/Spinner";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import {
faPencilAlt,
faCommentDots,
faMouse,
} from "#fortawesome/free-solid-svg-icons";
import BallonEditor from "#ckeditor/ckeditor5-editor-balloon/src/ballooneditor";
import BalloonEditor from "#ckeditor/ckeditor5-editor-balloon/src/ballooneditor";
import { editorConfiguration } from "../../components/editor/EditorConfig";
const PostDetail = (req) => {
const dispatch = useDispatch();
const { postDetail, creatorId, title, loading } = useSelector(
(state) => state.post
);
const { userId, userName } = useSelector((state) => state.auth);
console.log(req);
useEffect(() => {
dispatch({
type: POST_DETAIL_LOADING_REQUEST,
payload: req.match.params.id,
});
dispatch({
type: USER_LOADING_REQUEST,
payload: localStorage.getItem("token"),
});
});
const onDeleteClick = () => {
dispatch({
type: POST_DELETE_REQUEST,
payload: {
id: req.match.params.id,
token: localStorage.getItem("token"),
},
});
};
const EditButton = (
<div>
<Row className="d-flex justify-content-center pb-3">
<Col className="col-md-3 mr-md-3">
<Link to="/" className="btn btn-primary btn-block">
Home
</Link>
</Col>
<Col className="col-md-3 mr-md-3">
<Link
to={`/post/${req.match.params.id}/edit`}
className="btn btn-success btn-block"
>
Edit Post
</Link>
</Col>
<Col className="col-md-3">
<Button className="btn-block btn-danger" onClick={onDeleteClick}>
Delete
</Button>
</Col>
</Row>
</div>
);
const HomeButton = (
<div>
<Row className="d-flex justify-content-center pb-3">
<Col className="col-sm-12 com-md-3">
<Link to="/" className="btn btn-primary btn-block">
Home
</Link>
</Col>
</Row>
</div>
);
const Body = (
<div>
{userId === creatorId ? EditButton : HomeButton}
<Row className="border-bottom border-top border-primary p-3 mb-3 d-flex justify-content-between">
{(() => {
if (postDetail && postDetail.creator) {
return (
<div>
<div className="font-weight-bold text-big">
<span className="mr-3">
<Button color="info">
{postDetail.category.categoryName}
</Button>
</span>
{postDetail.title}
</div>
<div className="align-self-end">{postDetail.creator.name}</div>
</div>
);
}
})()}
</Row>
{postDetail && postDetail.comments ? (
<div>
<div className="d-flex justify-content-end align-items-baseline small">
<FontAwesomeIcon icon={faPencilAlt} />
<span> {postDetail.date}</span>
<FontAwesomeIcon icon={faCommentDots} />
<span>{postDetail.comments.length}</span>
<FontAwesomeIcon icon={faMouse} />
<span>{postDetail.views}</span>
</div>
<Row className="mb-3">
<CKEditor
editor={BalloonEditor}
data={postDetail.contents}
config={editorConfiguration}
disabled="true"
/>
</Row>
</div>
) : (
<h1>hi</h1>
)}
</div>
);
return (
<div>
<Helmet title={`Post | ${title}`} />
{loading === true ? GrowingSpinner : Body}
</div>
);
};
export default PostDetail;
It seems to be a small syntax error, your final return statement should be :
return (
<div>
<Helmet title={`Post | ${title}`} />
{loading === true ? <GrowingSpinner /> : <Body />}
</div>
);

How can I do to see "The text is saved." after clicking on submit on my modal?

I have a modal and I am trying to have only this text on my modal after clicking on submit : "The text is saved.". Di you know how can I do to get that ?
I mean I have that :
and when I cick on submit I want that :
Here is my code :
import React, { Fragment } from "react";
import { render } from "react-dom";
import "./style.css";
import { ModalButton } from "react-modal-button";
const App = () => (
<div className="container">
<h1 className="title">React Modal Button</h1>
<hr />
<ModalButton
buttonClassName="button"
windowClassName="window-container"
height={400}
modal={(props) => (
<Fragment>
<header className="modal-card-head">Title</header>
<div className="modal-card-body">
Content
<input class="input" type="text" placeholder="Text input" />
<hr />
<textarea class="textarea" placeholder="e.g. Hello world" />
</div>
<footer className="modal-card-foot u-justify-content--flex-end ">
<button onClick={props.closeModal} className="button">
Cancel
</button>
<button className="button is-primary">Submit</button>
</footer>
</Fragment>
)}
>
Open Modal
</ModalButton>
<hr />
<ModalButton
buttonClassName="button"
windowClassName="window-container"
modal={(props) => (
<Fragment>
<header className="modal-card-head">Title</header>
<div className="modal-card-body">Content</div>
<button onClick={props.closeModal} className="button">
Cancel
</button>
</Fragment>
)}
>
Open Another Modal
</ModalButton>
</div>
);
render(<App />, document.getElementById("root"));
Or there My code
Do you know how can I do ?
Thank you very much !
here is how you can do it, I have created a function named "handleSubmitClicked" that will be triggered whenever submit will be clicked, you can add code of show modal there
import React, { Fragment } from "react";
import { render } from "react-dom";
import "./style.css";
import { ModalButton } from "react-modal-button";
function handleSubmitClicked() {
alert('submit clicked')
}
const App = () => (
<div className="container">
<h1 className="title">React Modal Button</h1>
<hr />
<ModalButton
buttonClassName="button"
windowClassName="window-container"
height={400}
modal={(props) => (
<Fragment>
<header className="modal-card-head">Title</header>
<div className="modal-card-body">
Content
<input class="input" type="text" placeholder="Text input" />
<hr />
<textarea class="textarea" placeholder="e.g. Hello world" />
</div>
<footer className="modal-card-foot u-justify-content--flex-end ">
<button onClick={props.closeModal} className="button">
Cancel
</button>
<button onClick={() => {handleSubmitClicked()}}
className="button is-primary">Submit</button>
</footer>
</Fragment>
)}
>
Open Modal
</ModalButton>
<hr />
<ModalButton
buttonClassName="button"
windowClassName="window-container"
modal={(props) => (
<Fragment>
<header className="modal-card-head">Title</header>
<div className="modal-card-body">Content</div>
<button onClick={props.closeModal} className="button">
Cancel
</button>
</Fragment>
)}
>
Open Another Modal
</ModalButton>
</div>
);
render(<App />, document.getElementById("root"));

Component not loading when route changed

I am using Preact. I first tried preact-router then wouter for routing, but the problem still exists for one specific component. Here is the main entry where all routes defined:
import { h, Component } from 'preact';
import { Route } from "wouter-preact";
import Header from './partials/header';
import Home from './pages/home';
import News from './pages/news';
import Article from './pages/article';
export default class App extends Component {
render() {
return (
<div id="app">
<Header />
<Route path="/"><Home /> </Route> // working perfectly
<Route path="/a/:article"> <Article /> </Route> // not working
<Route path="/n/:newspaper"><News /> </Route> // working
</div>
);
}
}
and here is the simplified second component which is working perfectly :
import { h, Fragment } from 'preact';
import { Link, Route } from "wouter-preact";
import useFetch from '../../utils/ajax';
export default function News() {
const url = window.location.pathname.split('/');
const { data, loading } = useFetch(domain + '/api/v1/news/?newspaper=' + url[2]);
return (
<Fragment>
{loading ? (
// loading indicator
) : (
<main role="main">
<div className="py-5">
<div className="container">
<div className="row">
{data.results.map((nisha, index) => (
<div className="col-sm-6" key={index}>
<div className="col-md-10" >
<div className="card mb-2 shadow-lg" style={{ border: 'none' }} >
<Link href={'/a/' + nisha.slug}>
<img className="card-img-top" src={ nisha.cover_image } alt={ nisha.slug } />
</Link>
<div className="card-body">
// body
<div className="card-footer text-muted">
// footer
</div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</main>
)}
</Fragment>
);
}
and finally the problematic component, when I click any link from previous component, browser url changing but the component is not loading (there is no debug console message in browser console).
export default function Article() {
console.log("loaded");
return (
<div className="main">
<div className="py-5">
<div className="column">
<div>example article</div>
</div>
</div>
</div>
);
}

Categories

Resources