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.
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'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.
I'm building an Express-React-Node app that I want to deploy on Google App Engine.
As I'm following several tutorials I've encountered these two apps architecture:
https://github.com/BalasubramaniM/react-nodejs-passport-app/tree/master/src
and
https://hackernoon.com/m-e-r-n-stack-application-using-passport-for-authentication-920b1140a134
I'd like to understand the differences.
The first one is only one app with Webpackand Babel.
On the client-side, I have a App.jsx file and Index.html file.
This is the App.jsx file:
import React from 'react';
const App = () => (
<div className='app'>This is a React app</div>
);
export default App;
And this is the html file:
<!DOCTYPE html>
<html>
<head>
<title>A Web App</title>
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="./bundle.js"></script>
</head>
<body>
<div id="app">This is an Express App</div>
<script>
ReactDOM.render(
React.createElement(App.default),
document.getElementById('app')
);
</script>
</body>
</html>
The second one comes with a client app and a server app.
There is a index.jss file with the following code :
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import { Route, Switch } from "react-router-dom";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/" component={App} />
</Switch>
</BrowserRouter>,
document.getElementById("root")
);
registerServiceWorker();
and a App.js file with the following code:
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import queryString from "query-string";
class App extends Component {
componentWillMount() {
var query = queryString.parse(this.props.location.search);
if (query.token) {
window.localStorage.setItem("jwt", query.token);
this.props.history.push("/");
}
}
render() {
return (
<div className="App">
//some stuff here
</div>
);
}
}
export default App;
There is nothing related to react in the html file.
I kind of understand that with the first project the rendering part is mixed within the html file but I'm not really able to understand the differences and does things articulate in one app and the other.
The 2nd one appears to be using the create-react-app engine to generate the scaffolding and starter files. The 2nd example incorporates JWT user authentication that gets stored in local storage whereas the first does not appear to do so. Additionally, the 2nd example leverages React Router which allows you to build a single-page web application with navigation without the page refreshing as the user navigates. React Router uses component structure to call components, which display the appropriate information and allows you to add routes rapidly to build out the navigation. That is how the App component is being rendered within the imported Route component prop in index.jss. And if someone adds another Route with another path containing another component prop like this:
<Route path="/another-path" component={SubComponent} />
you could then access that component by traveling to baseURL/another-path
Token authentication and the use of React-Router are the primary differences between these two projects.
There are no differences. Both versions will call ReactDOM.render with an App element.
If you compile the second version using webpack, webpack will bundle all files together and will produce the same code as your first, partly manual solution.
I have built authorization into my React App using passport.js, and I would like to, in my App.js file, fetch my authorization routes to see if a user is logged into the app, or if nobody is logged in.
To help with the question, I have shared a condensed version of my React App's App.js file, and Index.js file.
// App.js File
// Import React Libraries, Routes, Container Pages
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Route } from 'react-router-dom';
import { userActions } from './actions/auth/auth-actions.js';
import GameLanding from './containers/StatsPages/Game/GameLanding';
import AppFooter from './components/AppFooter';
// And Create The App
class App extends Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.props.dispatch(userActions.authorize());
}
render() {
return (
<div>
<Route exact path='/stats/games' render={() => <GameLanding userInfo={this.props.userInfo} />} />
<AppFooter />
</div>
);
}
}
// export default App;
function mapStateToProps(reduxState) {
return {
userInfo: reduxState.authorizedReducer.userInfo,
authorized: reduxState.authorizedReducer.authorized,
loading: reduxState.authorizedReducer.loading
};
}
export default connect(mapStateToProps)(App);
... my entire App.js file has ~15 Routes components, and (part of) my goal with my App.js file is to fetch the authorized and userInfo props, and pass these to the components in the various routes. I showed an example where I pass the userInfo prop to the GameLanding component.
Here is how I have set up my Index.js file.
// Index.js
// Import Libraries
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
// Import CSS and the App
import App from './App';
import 'react-table/react-table.css';
import './index.css';
import './App.css';
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root'));
My current problem is as such: For some reason, fetching the userInfo and authorized props is breaking my app. I am unfortunately getting no error messages... rather, all of the react-router-dom Links in my app are simply not working... clicking them changes the url, but the pages of my app no longer change...
My questions are then, (a) am i allowed to fetch authorization data in App.js in the manner I am doing so (using connect, with mapStateToProps, etc.), or am I doing this all wrong?
Whether or not somebody is logged into my app is an app-wide thing, not a page-specific thing, and I figured for this reason (also to prevent having to fetch auth props in many many container pages) that App.js is the best place to grab these props.
Any thoughts on why my app is breaking, or how else my App.js file should look (I am ~99% sure my index.js is fine), would be greatly appreciated! Thanks!
Edit: For reference, doing the following: (i) importing userActions, (ii) calling userActions.authorize() in componentDidMount, (iii) including the mapStateToProps and connect on bottom of app, etc. works for loading the auth props in any of my container components. e.g. if i had this code in my GameLanding component, it doesnt break the react-router-dom Links app-wide in the same manner that it does when this code is in App.js. Hence the title of the question. Thanks!
1) Reason for app breaking:
I am assuming userInfo and authorized props will be undefined, as component renders initially before componentDidMount runs and you have not handled undefined props. You could also pass default props for these props.
2) Better structure for authorization
I am assuming you need to authenticate each route for authorization.
i) Create routes file and enter all routes for your app.
ii) <Route exact path='/stats/games' component={GameLanding} onEnter={reqAuth}/>
Inside reqAuth function you should check if the user is authorized for that route or not.
iii) Inside App component call action for fetching data, store in store and use GameLanding as child component and pass props only when they are defined.
That is not whole code, but should give you gist.
Happy Coding!!!
I am building SSR React app with razzle tool. Server is using express framework. I would like to load React components dynamically according to value included in API response.
I have folder structure like:
views
- default
-- Home.js
- theme1
-- Home.js
I am using SSR. On the server I have
const markup = renderToString(
<Provider store={store}>
<StaticRouter context={context} location={req.url}>
<App theme={theme} />
</StaticRouter>
</Provider>
);
Inside App component, I need to import component from corresponding subfolder or if its absent than import default component from the default subfolder. There can be many theme subfolders so I can't import all the components manually.
Should this by done on server by express or is there another way?
Thanks
Are you looking for something like this? I'm not quite sure if you are using server side rendering.
import DefaultComponent from './views/default.js';
import Theme1Component from './views/theme1.js';
this.state = {
visibleDefault: true
}
You can then simply update the state base on the response.
Then in your render you can have this
render(){
return(
{ visibleDefault ? <DefaultComponent/> : <Theme1Component/> }
)
}