Anchor links working locally but not when deployed (React) - html

I have a one page react app and I have a menu with anchor links set up like this:
Story
And in the target div, I have it like this:
<div id="story" class="py-16 xl:py-36 px-4 sm:px-6 lg:px-8 bg-black overflow-hidden">
When I do npm start to run the page locally, the anchor links work as intended. When I deploy it to the web, the links give me a 404.
Why would this happen?
EDIT:
I read about react-router-dom and tried to implement it, but I am getting strange behavior.
I imported this at the top of App.js:
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
I wrapped the enter contents of the first App() function in <Router></Router>.
Then inside the App() section, I set up this:
<Switch>
<Route path="/about">
<About />
</Route>
</Switch>
My About link is set up like this:
<a href="/about" class="text-base text-gray-300 hover:text-white">
About
</a>
Then at the very bottom of the App.js document, below the , I have this:
function About() {
return (
<><h2>About</h2>
<br />
<p>Test</p></>
);
}
But what happens when I click the About link is it re-renders the entire main page and the text "About Test" at the bottom.
What do I need to do to get this to render as an entirely new page?

As far as I am aware you can not use <a> tags for internal navigation in react. I don't know why it works locally for you.
With react you are creating single page applications (SPAs), you have 1 html page that can be found in the public folder. If you created the app using create-react-app, you will see within it, an element such <div id=root> </div>. That is the targetted rendering location, where you will be rendering the entire app by dynamically changing the html within it as you interact with the page.
However, when you typically click on an <a> tag, we are usually taken to different html page. Here I would assume the server is trying to retrieve either the App.html page or index.html page from within public/App folder.
React does not typically come in with built in routing functions/components. It leaves it up to the user to implement. So user's usually turn to a package like react-router along with react-router-dom/native (depending on react or react native) to get those functionalities.
Answer to Updated Question
Change your <a> tags to <Links> as follows
<Link to='/about' className='tailwind_classes'>About</Link>
<Link> tags are meant to replace <a> tags if using react-router-dom for navigation.
When you click on it, your <Router> is notified and lets the <Switch> figure out which <Route> to render
Update
Okay let's say you have a header where your links are, and we have 2 components <Home> and <About>
Then this is how your <App> should look like
return(
<Router>
{/* The header can be it's own component*/}
<header>
<Link to='/home' className='tailwind_classes'>Home</Link>
<Link to='/about' className='tailwind_classes'>About</Link>
</header>
<Switch>
{/* exact makes sure path has to be exactly '/' */}
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
<Router>
)
You could obviously write the markup for the <Home> & <About> component directly inside the <Route>s but would not advise. The header can also be it's own component and it will always stay on the screen since it is outside the switch, making it kind of a global thing.
The to prop of Link must match the path prop of one of the Route
Basically when you click on a link, the url changes. The Router is notified who then passes the new url to the Switch, which then acts like a switch case statement to match the url and renders/mounts the JSX inside the matched Route after removing/unmounting what was previously there.
Read the read the react-router-dom documentation for further clarification

Related

How to return HTML in React

When developing my project, I look at others for an example. When I looking at Instagram website. I see the class name of html is change when user is login. May I know how to achieve that actually? As what I know, react only live in one of the div in html structure.
// This code will render a component in the html root.
ReactDOM.render(<App />, document.getElementById('root'));
// But how to serve a whole new html file in react
How to serve a whole new html file in react? Is it violate the concept of react?
HTML and Document body are outside the React realm of DOM handling. So you can use good old querySelector for setting the class names.
function LoginPage() {
useEffect(() => {
document.querySelector('html').classList.add('login-page');
}, []);
return (
// stuff
);
}
A handy package is the React ecosystem for these is React Helmet
import {Helmet} from "react-helmet";
function LoginPage() {
return (
<Helmet>
<html className="loginPage" {...anyOtherStuff} />
<body {...attributesOnBody} />
</Helmet>
);
}
If you would like to add nodes that are adjacent to the root node in the body or React provides you with a solution called Portals that can render anywhere.
For the abiity to change index.html itself, you would not be building yourself a SPA anymore which seems to be case to use React.
you should add a class to your html input to retrieve it.
Here is an exemple :
import React from 'react';
import ReactDOM from 'react-dom';
class X extends React.Component {
render() {
return <h2>TEXT HERE</h2>;
}
}
ReactDOM.render(<X/>, document.getElementById('root'));
React works in a way that attaches itself to some DOM element. In your case, you are attaching it to some element with id of root.
TLDR;
Your index.html will contain the code of your application inside the element with root id during the runtime in the browser. You can see it by inspecting it using browser developer tools.
Your <App /> is the root of your application and if you use dev tools of your browser and you inspect the DOM tree you will see components in there. They are just dynamically attached by React (ReactDOM) and React is in the control of when and how things are rendered.
If your components look something like:
import React from 'react';
function App() {
return <h1 className="title">Hello!</h1>;
}
In Dev tools your DOM structure will looks something like this:
<div id="root">
<h1 class="title">Hello!</h1>
</div>
Here you can see that you have element with root id that you attached your <App /> before and you can see the content of <App />, <h1 class="title" /> together with classes.
That is also how Instagram works and most of the single-page applications or SPAs in short.
There is also a possibility to render static version of your application.

To change the value of the URL in the browser, but not the React component to be rendered

I have a link <Link to = "country/USA"/>
Then the route <Route path="country/:countryId" component={Country}/>
When the component "Country" is rendered, the browser Url is
http://<domain>/country/USA
Is there a way to change the display of the browser Url as http://<domain>/country, and have the "countryId" only as the Route props in the Country component.
Have gone through
https://reacttraining.com/react-router/web/api/BrowserRouter
https://github.com/ReactTraining/react-router
Couldn't find anything helpful.
Any suggestions?
Thanks!
Unless you're okay with USA being part of a query string, there's nothing much you can do within React Router (snippet comes from react-training site)
<Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}/>
Another alternative that doesn't involve router is to have a Container component that receives USA as props and then programatically render the component that you want. I'd say that's way too much work for something that makes sense to be shown in the URL
EDITED
One way to do it via component would be something like this:
<Route path="country/some-static-keyword" render={() => <Country countryId={this.props.countryId}/>}/>

Which of the following is the correct way to create links for the react components?

1. <a href={‘https://www.facebook.com/’}>Link1</a>
2. <a link-to={testContainer}>Link1</a>
3. <a href={[to-component]}>Link1</a>
4. <a href-to={‘https://www.facebook.com/’}>Link1</a>
Sorry, but I am confused which is the correct answer. Which and why?
You can try it in your React app.
It's a correct HTML attribute for React
<a link-to={testContainer}>Link1</a>
One of the options not mentioned in your question is using react-router for routing needs. This would involve creating routes which would be later used to navigate the different components. The example below shows a sample Router.
<Router >
<Route path="/" component={Root}>
<Route path="home" component={Home}/>
</Route>
</Router>
You can use the Link object to create dynamic links which would navigate to the appropriate component.Using the above example, this would look like
<Link to="/home">Home</Link>

Simple Website that Shows Reactjs + Redux

I am trying to learn redux and react and I sort of getting how it all works but every example I see is so simple that when I started my own webpage I got stuck rightway.
All the examples are just one or 2 components on a blank page, they might be styled to look nice but there is nothing else, no headers, footers, no nav bars nothing.
So for me, I have a header, footer, main container and a side bar, that lists all the users items that are clickable.
I have no clue where to write the static html(are they dump components or just html?), I don't know how to render multiple smart components(side bar, main container what displays contents of what was clicked on in side bar).
Every tutorial I see gets everything written to the one div
<div id="root"></div>
Do I have many of these for each area and then have mutiple of these?
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<div id="root"></div> in your index.html is the "target" for your React application and only appears once.
Similarly, you only need to render App to the reactDOM once. Your App component can then render multiple components itself, for example
import React, { Component } from 'react';
import Header from './components/header';
import Footer from './components/footer';
import MainContainer from './components/main_container';
class App extends Component {
render() {
return (
<div>
<Header />
<MainContainer />
<Footer />
</div>
);
}
}
This assumes you have created Header, Footer and MainContainer components. Your App component can be thought of (very simplistically) as a larger component that contains multiple components. Therefore, if you render App to ReactDOM you are effectively rendering the other components contained within App.
Please note: this assumes the use of webpack, babel and es6.
Facebook has a great tutorial for building app in react-native, this section explains redux things:
http://makeitopen.com/tutorials/building-the-f8-app/data/
This section is basically how to architect in ReactJS + Redux, so don't be afraid the react-native things, this section is almost the same as in web apps.
you can find code here

Re-using a react component across different routes

We ran into a situation where we have edit page and create page sharing the same component. The router looks like below.
<Route path="/" component={AdrApp}>
<IndexRoute component={ManageDrugPage}/>
<Route path="cdicms-adr-ui" component={HomePage}/>
<Route path="create-adr" component={ManageADRTermPage}/>
<Route path="manage-adr/:id" component={ManageADRTermPage}/>
As we see above the 'ManageADRTermPage' component is used by 'create-adr' route and 'manage-adr' route.
The problem with this is that we have a dropdown component implemented using react-bootstrap.
When the user is in the edit page and the user now selects the create page the page is not transitioning. The edit page stays right there. we do this.history.pushState(null, '/create-adr') when the 'create' dropdown is clicked.
How could we workaround this issue?
Easy workaround would be to have a simple CreateADRTermPage component, that's a wrapper for your ManageADRTermPage.
Or change your ManageADRTermPage component to EditADRTerm, and have both CreateADRTermPage and ManageADRTermPage be simple wrappers of it.