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
Related
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
Visit Next.js and notice the page request in the network tab. Preview shows not just the HTML but completely pre-styled page.
When we use Styled-Components and Material-UI they have exposed ServerStyleSheet which is used for serving the required styles for the first render within the HTML.
import { ServerStyleSheet } from 'styled-components'
import { ServerStyleSheets } from '#material-ui/core/styles'
How can we achieve same output when using react-bootstrap or custom css like test.css?
Do you care if its a test.css or React bootstrap - Instead why not just inline all critical stylesheets?
It might be worth trying out their experimental feature
Add experimental: { optimizeCss: true } to next.config.js
Install critters#0.0.7 as a dependency
Via How to inline CSS in the head tag of a NextJS project?
Add your style file on the the _app file, you can create this file inside the pages directory in nextjs
import { AppProps } from "next/app";
import 'bootstrap/dist/css/bootstrap.min.css';
import "../your_style.css";
function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default App;
for react-bootstrap , you need to add npm i react-bootstrap bootstrap
Nextjs allows you to display SSG/SSR pages and javascript-disabled
users will still be able to see your app but the layout will be messy
if you use react-bootstrap components to build your layout.
To use react-bootstrap at SSR:
Install :
npm i react-bootstrap bootstrap
Import bootstrap styles in your _app.js:
import 'bootstrap/dist/css/bootstrap.min.css';
You can then use your react-bootstrap components as you would do in reactjs:
import {Container, Row, Col} from 'react-bootstrap';
const Layout = () => (
<>
<Container fluid>
<Row>
<Col>
<p>Running on Next.js at SSR</p>
</Col>
</Row>
</Container>
</>
);
export default Layout;
use Tailwind css
https://tailwindcss.com/
We can simply use classes and it make everything super easy for you design
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.
I am following the basic 'Tour of Heros' tutorial and sort of adding my own needed elements as I go (bootstrap, ng-bootstrap etc) and I want to grab the 'selected hero' from hero details when I reach it and put the name of the hero in a navbar component.
Like so, but obviously with a way to access the selected hero
<div *ngIf="selectedHero">
<li class="nav-item">
<div class="nav-link" routerLink="/detail" routerLinkActive="active">{{selectedHero.name}}</div>
</li>
</div>
My navbar is called by app.component.html above the routing outlet
<app-navbar></app-navbar>
<div class="container">
<router-outlet></router-outlet>
</div>
I have already looked up several questions related to this sort of thing but havnt really found anything made sense or worked when I tried it (I am assuming I am not doing them correctly or a similar issue)
I am new to angular and I feel like this sort of access is something I should know asap
I have seen 'emitters' and 'parent-child relationship' etc but not sure how to go about that with my navbar and the selected hero. The tutorial im following (that has all the code that im working with) is: https://angular.io/tutorial
Edit Ive also considered just calling the 'navbar' component within every other main component (as in, within 'hero-detail.component.html' above the actual information) but I think that goes against standards/repeating code?
The hero details component and the navbar component have no relationship, so to share data between them you simply need to create a shared service between them that can pass data back and forth like this:
selected-hero.service.ts
import {Injectable} from '#angular/core';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
#Injectable()
export class SelectedHeroService {
selectedHero = new BehaviorSubject<string>('Default Name Of Hero To Be Shown Goes Here');
selectedHeroObservable = this.selectedHero.asObservable();
changeSelectedHero(newHero:string):void{
this.selectedHero.next(newHero)
}
}
and then in your navbar component, you can read the selected hero like this:
navbar.component.ts
constructor(private sh: SelectedHeroService ) {
this.sh.selectedHeroObservable
.subscribe((hero) => {
//add your logic here!! for now I'm just gonna console log the selected hero
console.log(hero);
});
}
To set a new hero in you heroes details component you call this method:
hero-details.component.ts
changeSelectedHero(){
this.sh.changeSelectedHero('My New Selected Hero');
}
and don't forget to add the service in the provides arrays and both of the components in the declarations array of the same module so you don't get any errors. Also, don't forget to unsubscribe from the selectedHeroObservable to avoid memory leaks.
Component interaction in Angular could be simplified as i use angular at least to three ways: #ViewChild, EventEmitter (Output) or Input.
Viewchild is as it sound when you have a child component and you could set variable declaration (#) in the template to directly have access to methods on the child component.
Eventemitter is used in the child component when you want to notify the parent.
Input is used to set a property in a child.
A part from these three ways to communicate within components there is also services. I use this aproach when the components are too far from each other.
And to answer your question i would go with the service aproach. Have a look at subjects. Check out this plunker!!
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
http://plnkr.co/edit/FHIPt1?p=preview
I have been using React and look to use Polymer tags inside of React. React does not recognize Polymer tags as React only handles basic DOM tags. Is there a way to add the Polymer tags to React DOM library?
Yes, it is possible.
Create a polymer element.
<link rel="import" href="../../bower_components/polymer/polymer.html">
Polymer({
is: 'calender-element',
ready: function(){
this.textContent = "I am a calender";
}
});
Make the polymer component a html tag by importing it in a html page. E.g. import it in the index.html of your react application.
<link rel="import" href="./src/polymer-components/calender-element.html">
Use that element in the jsx file.
'use strict';
import React from 'react';
class MyComponent extends React.Component{
render(){
return (
<calender-element></calender-element>
);
}
}
export default MyComponent;
Is it possible to use Polymer inside of React?
Short answer: not really.
Long answer: kinda. You have to create components which directly create the nodes and manipulate attributes. There are also other considerations for children of the element, etc.
Is it possible to use React inside of Polymer?
It's pretty much the same answer this way, you'd have to wrap a React component in a polymer element.
Why?
Polymer (based on web components), and React (a ui component library), are both based on 'components'. Because there's no single way to express a component in web, you'll need to bridge between the various libraries. The same holds true for questions about 'react in angular', 'jquery plugin in react', 'knockout in jquery plugin', 'react in backbone', 'angular with polymer elements which use backbone and react with polymer elements which use angular', etc.
In a case like angular with polymer, you might think it's very simple, but polymer doesn't know about evaluating angular expressions, or any kind of declarative callbacks. You need a bridge in nearly every case, and they're never pretty.
this is a fairly old question but how about https://www.npmjs.com/package/react-polymer ? isn't this a support of polymer components for react?
import reactPolymer from 'react-polymer'; //IMPORTANT: Must be imported before React.
import React from 'react';
reactPolymer.registerAttribute('raised');
reactPolymer.registerAttribute('url');
reactPolymer.registerEvent('response', 'onResponse');
<paper-button raised>another button</paper-button>
<iron-ajax url="http://example.com/" onResponse={this.handleResponse} />
Answer according to current stages of react and polymer
Since this question was asked a while ago and a lot has changed since then, I'd like to add that you can now use polymer elements in react directly but for your custom attributes and events it causes problem it can easily be handle by using react-polymer, It has support for almost all elements, with exception of gold-* elements.
Why would you want to use Polymer with react?
It can further simplify your development process or make it a big mess. It depends on how you use it
Speed of development and ease of use offered by polymer components is unrivaled.
React can further break down your components comprising of polymer components, into manageable pieces.
Simply because, react and JSX is love.
Hey why the hell not??
The answer is YES. But it is not straight forward. So, I tried following some documentations which are around in fact even the official one but the best was this: https://medium.com/jens-jansson/start-using-web-components-in-react-6ccca2ca21f9
I followed the steps mentioned and it worked! I am also mentioning the github repo wherein I tried to integrate the vaadin datepicker and also one of the polymer element paper-input. https://github.com/manit815/react-with-webcomponent
Yes, you can use Polymer element inside react.
Create Polymer element
import { LitElement, html } from 'lit-element';
export class CustomButton extends LitElement {
static get properties() {
return {
isDisabled : { type: Boolean },
buttonType: { type: String },
};
}
constructor() {
super();
this.isDisabled = false;
this.button = 'button';
}
render() {
return html`
<button>
<slot></slot>
</button>
`;
}
}
customElements.define('polymer-button', CustomButton);
Import the element into an HTML file using <script type="module">.
Use the import statement (as shown above) to import it from another ES6 module.
<script type="module" src="./polymer-button.js">
Once you've imported it, you can use a custom element just like you'd use a standard element.
import React from 'react';
export const PolymerButton = () => {
return (
<polymer-button />
)
}
I just tried this today and I was able to successfully use the material elements from their element catalog. I haven't gotten around to testing it thoroughly, but as far as using the tags in React goes, it works and all the html and css is there.
To use existing elements, just follow their using elements guide.