Checked the code and cannot find where I need to put a semicolon.
Here is error.
Here is the code.
It should be like this
const Routes = (props) => ( ... )
It should be like this
const PropsPage = () => { return ( <h3>Props Page</h3> );};
for a
const App = () => {
return (
<section className="App">
<Router>
...
<Link to="/404-not-found">404</Link>
<Link to="/props">Passing Props</Link> <Switch>
...
<Route exact path="/props" component={PropsPage} /> <Route component={NoMatchPage} />
</Switch>
</Router>
about with browser reload
</section>
);
};
Passing function as a component props in Route component
const PropsPage = ({ title }) => {
return (
<h3>{title}</h3>
);
};
Related
// src/Login.tsx
const Login = () => {
<h1>Success</h1>;
};
export default Login;
// src/Router.tsx
export default () => {
const CLIENT_ID = process.env.REACT_APP_KAKAO_API_KEY;
const REDIRECT_URI = "http://localhost:3000/api/user/kakao/callback";
const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;
return (
<Router>
<div className="App">
<Switch>
<Route exact path="/">
<h1>
<a href={KAKAO_AUTH_URL}>
<Login />
</a>
</h1>
</Route>
<Route path="/oauth/kakao/callback">
<Auth />
</Route>
<Route path="/profile">
<Profile />
</Route>
</Switch>
</div>
</Router>
);
};
I see an error.. 'Login' cannot be used as a JSX component.Its return type 'void' is not a valid JSX element.
I tried to reference it on here, but I can't find a solution. What should I do?
Your login component needs return anything.
// src/Login.tsx
const Login = () => {
return <h1>Success</h1>;
};
I'm updating a sourcecode from react-router-5 to version 6. So far I'm getting this error:
Error: [div] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
The bug is triggered when I activate a link in this component(QuoteItem.js):
const QuoteItem = (props) => {
return (
<li className={classes.item}>
<figure>
<blockquote>
<p>{props.text}</p>
</blockquote>
<figcaption>{props.author}</figcaption>
</figure>
<div className={classes.item}>
<Link className='btn' to={`/quotes/${props.id}`}>View Fullscreen</Link>
</div>
</li>
);
};
in another component (VerQuotes) I defined the routes:
const VerQuotes = () => {
return (
<div>
<main>
<Layout>
<Routes>
<Route path="quotes" element={<AllQuotes />} />
<Route path="new-quote" element={<NewQuote />} />
<Route path="quotes/:quoteId" element={<QuoteDetail />} />
</Routes>
</Layout>
</main>
</div>
);
};
I'm kind of lost how to tackle the error, your comments will be highly appreciated.
Thanks a lot
Update
QuoteDetail
const QuoteDetail = () => {
const match = useNavigate();
const params = useParams();
const { quoteId } = params;
const { sendRequest, status, data: loadedQuote, error } = useHttp(getSingleQuote, true);
//const quote = DUMMY_NOTES.find((quote) => quote.id === params.quoteId);
useEffect(() => {
sendRequest(quoteId);
}, [sendRequest, quoteId]);
if(status === "pending"){
return (
<div className="centered">
<LoadingSpinner />
</div>
);
}
if(error){
return <p className="centered">{error}</p>;
}
if (!loadedQuote.text) {
return <p>No Quote Found!</p>;
}
return (
<Fragment>
<HighlightedQuote text={loadedQuote.text} author={loadedQuote.author} />
<Routes>
<Route path={match}>
<div className="centered">
<Link
className="btn--flat"
to={`${match}/comments`}
>
Load Comments
</Link>
</div>
</Route>
<Route path={`${match}/comments`} element={<Comments />}></Route>
</Routes>
</Fragment>
);
};
Issues
After tracing your code I found you had a couple issues in QuoteDetail component.
You used const match = useNavigate(); (so match is really the navigate function) but then later used match to attempt to form a path string for a Route.
The Route component's children prop is only for rendering nested routes. The error you see is the use of the div element that isn't a Route component.
Code
<Routes>
<Route path={match}>
<div className="centered">
<Link
className="btn--flat"
to={`${match}/comments`}
>
Load Comments
</Link>
</div>
</Route>
<Route path={`${match}/comments`} element={<Comments />}></Route>
</Routes>
Solution
Remove const match = useNavigate(); since it is not used, and place the div into the element prop of the Route. Change the path props to use relative routing from the current route path that's already been built up.
const QuoteDetail = () => {
const params = useParams();
const { quoteId } = params;
const { sendRequest, status, data: loadedQuote, error } = useHttp(
getSingleQuote,
true
);
//const quote = DUMMY_NOTES.find((quote) => quote.id === params.quoteId);
useEffect(() => {
sendRequest(quoteId);
}, [sendRequest, quoteId]);
if (status === "pending") {
return (
<div className="centered">
<LoadingSpinner />
</div>
);
}
if (error) {
return <p className="centered">{error}</p>;
}
if (!loadedQuote.text) {
return <p>No Quote Found!</p>;
}
return (
<Fragment>
<HighlightedQuote text={loadedQuote.text} author={loadedQuote.author} />
<Routes>
<Route
path="/"
element={
<div className="centered">
<Link className="btn--flat" to="comments">
Load Comments
</Link>
</div>
}
/>
<Route path="comments" element={<Comments />} />
</Routes>
</Fragment>
);
};
Params is undefined in ItemPage. I can't seem to see the issue here. Any takers?
Basically trying to create a dynamic path with Link
.
export default function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/catalog" component={Catalog} />
<Route path="/about" component={About} />
<Route path="/item/:nm" component={ItemPage}/>
<Route render={() => <h1>404: page not found</h1>} />
</Switch>
</Router>
)}
function Catalog() {
return (
<div className="Catalog">
{Routes.map((route, index) => {
return <p key={index}><Link to={`/item/${route.name}`}> {route.name} </Link></p>
})}
</div>
);
}
const ItemPage = ({match:{params:{nm}}}) => {
return (
<div>
<h1>Item {nm} Page</h1>
<ItemPage name={nm}/>
</div>
)
};
if you use react-router-dom package, then this method might help you then:-
ItemPage (use useParam hook):-
import { useParams } from 'react-router-dom'
const ItemPage = () => {
const { nm } = useParams()
return (
<div>
<h1>Item {nm} Page</h1>
<ItemPage name={nm}/>
</div>
)
};
I'm not sure if the way you have your props set up on ItemPage is exactly correct - in my experience using react-router I've always just used match as its own parameter without defining its properties like so:
const ItemPage = ({match}) => {
return (
<div>
<h1>Item {nm} Page</h1>
<ItemPage name={match.params.nm}/>
</div>
)
};
Another option could be to use the routecomponent props and do some destructuring to pull out match:
import { RouteComponentProps } from 'react-router';
const ItemPage : FC<RouteComponentProps> = (props) => {
const {match} = props
return (
<div>
<h1>Item {nm} Page</h1>
<ItemPage name={match.params.nm}/>
</div>
)
};
(see here: What TypeScript type should I use to reference the match object in my props?)
Basically the nested <ItemPage name={nm}/> was the issue. It should be replaced with a different component or HTML.
https://github.com/Tyler90901/webtech/pull/1/commits/16b337bc2e45ef0f06bc41f1fc060b87a8bc9d36
I'm a bit new to React and it is my first time using reach-router (or any kind of router really). What I'm trying to do is have a nested component inside one of my router links. Basically, within my ItemShop component, I want to have two more links to components (both of which are defined within my ItemShop component), and I want to display whichever component is selected under the navbar. It seems similar to something they do in the tutorial, but for some reason I seem to get an infinite loop when I click on a link.
Here is my top-level router, in App.js:
function App() {
return (
<div>
<Router>
<HomePage path="/" />
<ItemShop path="ItemShop" />
<Item path="ItemShop/:id" />
<Challenge path="Challenge" />
<Achievements path="Achievements" />
<BattlePass path="BattlePass" />
<Miscellaneous path="Miscellaneous" />
</Router>
</div>
);
}
And this is my ItemShop component where I'm trying to render the links, ItemShop.js:
render() {
// ... assigning arrays here
let Current = () => ( //...);
let Upcoming = () => ( //...);
return(
<>
<div className="nav-container">
<Navbar />
</div>
//...
<div>
<nav className="side-nav">
<Link to="/current">Current</Link>{" "}
<Link to="/upcoming">Upcoming</Link>
</nav>
<Router>
<Current path="current" />
<Upcoming path="upcoming" />
</Router>
</div>
//...
{this.props.children}
)
}
}
Again I am very new to Javascript/React as a whole, so it could just be a fundamental flaw. I have already sunk quite a few hours into this so I would really appreciate some guidance. Thank you for your time!
I tried using React-Router-Dom instead of reach-router. I made it so it renders both <Upcoming /> and <Current /> components inside of the <ItemShop /> component. You can check it out how I have done it below. I hope this helps.
// import React from "react";
// import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
export default function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/itemShop" component={ItemShop} />
<Route path="/itemShop/:id" component={Item} />
<Route path="/challenge" component={Challenge} />
<Route path="/achievements" component={Achievements} />
<Route path="/battlePass" component={BattlePass} />
<Route path="/miscellaneous" component={Miscellaneous} />
</Switch>
</Router>
</div>
);
}
const HomePage = () => {
return <div>Home Page</div>;
};
const ItemShop = () => {
const Current = () => {
return <div>Current</div>;
};
const Upcoming = () => {
return <div>Upcoming</div>;
};
return (
<div>
<div>Item Shop</div>
<Link to="/itemShop/current">Current</Link>{" "}
<Link to="/itemShop/upcoming">Upcoming</Link>
<br />
<br />
<Route
render={() =>
window.location.pathname === `/itemShop/current` ? (
<Current />
) : (
<Upcoming />
)
}
/>
</div>
);
};
const Item = () => {
return <div>Item</div>;
};
const Challenge = () => {
return <div>Challenge</div>;
};
const Achievements = () => {
return <div>Achievements</div>;
};
const BattlePass = () => {
return <div>BattlePass</div>;
};
const Miscellaneous = () => {
return <div>Miscellaneous</div>;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/6.0.0-beta.0/react-router-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I am using a simple boolean flag to set whether a user is logged in or out to do conditional rendering. I have doubled down with this flag to use it also as a way to logout. I am getting a TypeError that is saying my setIsLoggedIn is not a function, however I am using it in a similar way in another area of my program.
App.js :
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div className="App">
<Switch>
<Route
path="/login"
render={() => (
<Login
isLoggedIn={isLoggedIn}
setIsLoggedIn={setIsLoggedIn}
/>
)}
/>
</Switch>
</div>
);
A portion of the code for SignedInLinks component:
const SignedInLinks = ({ isLoggedIn, setIsLoggedIn }) => {
const handleLogout = (e) => {
e.preventDefault();
setIsLoggedIn(false);
}
return (
<li><NavLink to='/login' onClick={handleLogout}>Logout</NavLink>
</li>
)
The error is exactly 'TypeError: setIsLoggedIn is not a function'
Define handleLogout in App.js
const handleLogout = (e) => {
e.preventDefault();
setIsLoggedIn(false);
}
return (
<div className="App">
<Switch>
<Route
path="/login"
render={() => (
<Login
isLoggedIn={isLoggedIn}
handleLogout={handleLogout}
/>
)}
/>
</Switch>
</div>
);
Sample Application of Login/Logout using Hooks
Hooks.js
function Hooks() {
const [loggedIn, setLoggedIn] = React.useState(false);
const handleClick = e => {
setLoggedIn(!loggedIn);
};
return (
<div>
{loggedIn ? (
<SignOut handleClick={handleClick} />
) : (
<SignIn handleClick={handleClick} />
)}
</div>
);
}
export default Hooks;
SignIn.js
function SignIn(props) {
return (
<div>
<h3>Please signin</h3>
<button onClick={props.handleClick}>signin</button>
</div>
);
}
SignOut.js
function SignOut(props) {
return (
<div>
<h3>Yay....You are loggedin</h3>
<button onClick={props.handleClick}>signout</button>
</div>
);
}