I'm building a ReactJS website as part of a web dev bootcamp project.
I made a search feature using flask routes between the reactjs endpoints (../Language.js) and my Sqlite3 database.
http://localhost:3000/kanjisearch
How do I make the result of a search into an endpoint itself though? For example if a user searches for "german verbs" the browser displays something along the lines of:
http://localhost:3000/kanjisearch?=german+verbs
I want this so that when users hit the forward or back arrows on the browser, it takes the user to the previous search, NOT the previous page they were on.
Can I do this is react/javascript? Something else?
Thank you.
yes you can, you can use react-router-dom library
just do yarn add react-router-dom and create a route.js file and do the following
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import someScreen from "../somewhere" // this would be your Screen that you wanna show
const Routes = () => {
return (
<Router>
<Switch>
<Route path="/container/language/:language" component={someScreen} />
</Switch>
</Router>
);
};
export default Routes;
after that you have to fix your app.js file as the following
import React from 'react';
import './App.css';
import Routes from './router '; //the location of your router
function App() {
return (
<div className="App">
<header className="App-header">
<Routes/>
</header>
</div>
);
}
export default App;
go to your component and do export default withRouter(someScreen)
In your screen Since you have now a connected Class (to the routing) you can access match inside your props, this props is created by react-router and contains informations about what matched in this route : For exemple match.params.language would contains the :language from the route, meaning if u have /german+verbs
and now you can use the url like http://localhost:3000/container/language/german+verbs and then german+verbs
your parameters would be passed to your component as as
match.params = {
language: 'language+verbs'
}
use this is in your compDidMount method
Well... what language do you want to use? :-) . You can do it in any of those you mentioned.
Since you mentioned ReactJS first, you can do it in javascript by using the window.location object. Just set and read the hash. BTW the hash can be anything and is ignored by the browser, but your JS can look at it. Your url would look something like this:
http://localhost:3000/container/language/Language#search=german+verbs.
Related
I have a NextJS application where I have a home page (index.js) and two other pages About(about.js) & Contact Us(contact.js).
I have created a BaseLayour.js file with is wrapping NextJS's MyApp component in _app.js file.
import React from "react";
import BaseLayout from "../layouts/BaseLayout";
function MyApp(props) {
const { Component, pageProps } = props;
return (
<BaseLayout>
<Component {...pageProps} />
</BaseLayout>
);
}
export default MyApp;
This BaseLayout component looks like this -
import React from "react";
import SEO from "../components/SEO";
import Header from "../components/Header";
import Footer from "../components/Footer";
function BaseLayout(props) {
const { children } = props;
return (
<div>
<SEO />
<Header />
{children}
<Footer />
</div>
);
}
export default BaseLayout;
As you can see above in the BaseLayout file, there is an SEO component (React). It contains some common metadata for all the pages. I have an API(api/getmetadata/) that delivers all the metadata in JSON format.
This metadata is supposed to load on the server-side so that the page will be optimized for SEO.
How can we call the API in order to retrieve the data on each request but only on the server-side?
What I have tried till now -
Tried calling API in the SEO component itself, but it is not running on the server-side as it is just a React component.
Tried creating a React context, and called the API from SEO/BaseLayout components, the API call is still not being made from the server-side.
Tried using getServerSideProps in the index.js page to call the API and retrieve the data, which worked perfectly, but the problem is we need to share the data between all the pages, not just the index.js home page.
Any help will be appreciated, If we can somehow make the API call and retrieve the data in the SEO component, it will solve our problem.
Thank you in advance guys.
I have an application with this config for history:
import { createHashHistory } from 'history';
import { ConnectedRouter } from 'connected-react-router';
const history = createHashHistory({
hashType: 'slash',
});
...
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
But all my routes get appended by /#
ex: localhost:8080/ becomes: localhost:8080/#/
I already tried to update my packages as this question say but it didn't work.
The only thing that worked was change createHashHistory to createBrowserHistory, but I'm not sure what's the difference between them, and why createHashHistory is appending the /#
With hashHistory, it produces url like
http://yourwebsite.net/#page/xxx
With browserHistory, it produces url like
http://yourwebsite.net/page/xxx
Which one to use? In real-world products, browserHistory is mostly used. A rule of thumb is "if you are using a dynamic server that can handle dynamic URLs then you need to use the BrowserRouter component but if you are using a server that only serves static files then a HashRouter component is what to be used in this case."
In your code, hashType: 'slash' is just the default value.
I'm new to React Router and I'm working on the best way to route to react router.
What am I trying to achieve:
I just want the default route to navigate to /:tenantName/media_management/dashboard instead of /:tenantName/media_management when the Media Management tab is clicked.
Issue:
I'm explicitly checking if the route is initial route and then re-routing to /dashboard. This works but it's
very slow. I can notice the apparent lag when I click on
Media-management Tab.
Wanted to know if there is a better way of handling default route?
Router.js
import { Route, Redirect, Switch, useHistory } from 'react-router-dom';
const AsyncMediaManagement = lazy(() => import('#src/features/media-management/'));
<Route
path="/:tenantName/media_management"
component={withMainLayout(AsyncMediaManagement, 'MediaManagement')}
/>
Media-management.js:
if (contentTypeSelected === '') {
props.history.push(`/:tenantName/media_management/dashboard`);
}
Please help, I'm very new to react router and any help would be very much appreciated.
Try adding exact=true to your Routes
Can we see some more of your 's - do you have the default dashboard route above or below the one you have shown?
RR will match the first route that it finds if you don't add an exact=true prop to the route.
Most of the tutorials I am seeing use a express.js file to route all get and post requests. I am using a React component using react-router-dom, do I need to use express? If yes, what is the best way to do so? Here is what my app is looking like following along 1/4 of this tutorial so far: https://www.youtube.com/watch?v=WDrU305J1yw&t=1693s
The mongoose code is probably misplaced and breaks the app.
import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import mongoose from 'mongoose';
import '../styles/App.css';
import Input from './Input';
mongoose.connect(
'mongodb://admin-01:PW#node-log-shard-00-00-ecvwz.mongodb.net:27017,node-shot-log-shard-00-01-ecvwz.mongodb.net:27017,node-shot-log-shard-00-02-ecvwz.mongodb.net:27017/test?ssl=true&replicaSet=node-shot-log-shard-0&authSource=admin&retryWrites=true',
{
useMongoClient: true
}
);
class App extends Component {
render() {
return (
<div>
<div>
<Route exact path='/' component={ Input } />
</div>
</div>
);
}
}
export default App;
The best and correct way to do this is to have a backend server in whatever language you prefer(javascript, java, etc.) and connect this server with your database. Then in your react application when you need data from your database you will make a request to the server and the server will retrieve the data and them back to your react application.
I am building a list of people my company is working with. Since it is constantly updating with new people I decided to make a single page web app purely in React as a way to learn it since I am new to it and I wanted to learn it for sometime now.
I have index.js and people.js. In people.js I made an object for every person and they each have own atributes (age, location etc.).
Since I don't know how to do it properly I made for each person Home and Single component of it.
Home component is something like:
export class AnnHome extends Component{
render(){
return(
<div>
<Link to={{pathname: 'influencer/Ann',
component: 'AnnSingle'
}}>
<img
src={require('./img/ann.png')}
alt="{Kofs.name}"
className="Avatar rounded-circle"
/></Link>
<p>{Ann.name}</p>
</div>
)
}
}
Before that component I have defined object 'Ann' with it's info.
My question is:
How to make a one Home component and one Single Component like a template so when I go to /ann to fill SingleComponent with Ann info.
Home Component would be like a list of all clients (people):
https://www.w3schools.com/howto/howto_css_team.asp
something like this.
I currently have a lot of Home components that I've put manually.
Hopefully I described my problem, my english is rusty :D
Hopefully this can help get you started.
As I mentioned above, you want to use the React Router to listen to route changes. Then one specifies which component should be mounted for each route. Here I use the route to match on the individual's name (e.g. so /stace matches the element in people where the person's name attribute is Stace.
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
const people = [
{name: 'Stace', img: 'https://placeimg.com/200/200/people'},
{name: 'Marlo', img: 'https://placeimg.com/201/200/people'},
]
const App = props => (
<BrowserRouter>
<div>
<Switch>
<Route path='/stace' component={Person} />
<Route path='/marlo' component={Person} />
</Switch>
{people.map((p, idx) => <Link to={'/' + p.name}>{p.name}</Link>)}
</div>
</BrowserRouter>
)
const Person = props => {
const name = props['match']['path'].toLowerCase().substring(1);
const person = people.filter(p => p.name.toLowerCase() == name)[0]
return (
<div className='person'>
<img src={person.img || ''}></img>
<h2>{person.name || ''}</h2>
</div>
)
}
export default App;
This is of course only meant to demonstrate the router-related concepts. If you use create-react-app, run yarn add react-router#4.3.0 && yarn add react-router-dom#4.3.1, and replace App.js with the content above, you'll be able to preview the app and explore the ideas expressed above. Clicking on a name will change the route to that name and display the data for that name. Below I've clicked on Stace: