Preserve Input Values when switching between views in React - javascript

Situation: I have a several input components but depending on the route (react-router) different ones are shown.
Problem: I want the input values the user already entered to be preserved when switching back and forth between routes and dropping/re-adding input components.
I came up with two solutions so far: 1) Always render everything but hide via CSS if not to be shown (breaks the idea of React for me somehow)
2) Implement some kind of "input value store" in the flux architecture (pretty elabortate)
Any other ideas? Am I missing something more fundamental?

I would definitely go for the second approach, something Flux like. But if this is the only thing in your application that needs it, you can keep it very simple. Should be possible to implement in very few lines of code.
The benefit you get is that the Flux approach scales very well, so you won't have to rewrite it if the application grows.

Look at Dynamic Segments
If you have dynamic segments in your URL, a transition from /users/123 to /users/456 does not call getInitialState, componentWillMount, componentWillUnmount or componentDidMount. React-Router-Guide
You should use dynamic routes like this example:
<Route name="inbox" handler={Inbox}>
<Route name="message" path=":messageId" handler={Message}/>
<DefaultRoute handler={InboxStats}/>
</Route>
If you change the messageId(child component) you will still have the same state in the Inbox(parent) Component.
It will look something like this:
<Route name="search" path="/search/:query?/:limit?/:offset?" handler={Search} />

Related

How to change only one part of a webpage/ keep the same template throughout the site?

Ive made a homepage/ template for a website. However, to add more pages i would have to copy this template with the added content of each page. Obviously, this would mean changing every single page if i make a small change to the template.
How do i have a main index page and then for every other page just change the content?
You do not mention a library of any kind in your question, so I will recommend a JavaScript library to you: React.JS.
With React.JS, you could utilize the routing system and make your template be returned for every route. However, you could change the props on each route in order to change the content that you want to be changed. Here's an example, in unfunctional code, of what you can do in React.JS:
<Route path='/hi'>
<Template content={'Hello!'} />
</Route>
<Route path='/bye'>
<Template content={'Goodbye!'} />
</Route>
<Route path='/'>
<Template />
</Route>
To learn more about React, here's the official documentation: https://reactjs.org/docs/getting-started.html.
I really recommend that you use React for this situation, I think it would make the development a lot easier. If you are already using a library, give me a comment and I will try to help you out for that specific library.
You can do this by using JavaScript. Just select the tags that needs to be improved and change their content by doing something like this
document.queryselector('.classname' or '#idname').innerHTML="your new content";
If you want to change an image, then try doing
document.queryselector('.classname' or '#idname').src="url of your image";

Move between nested switches in react router v4

My application has nested switches and I am trying to work out how to create a link that will navigate from one to the other. The app is structured like this:
App
Main switch (/)
Assets switch (/assets/)
Table component with Link
Templates switch (/templates/)
Object viewer component to be linked too
The link component looks like this, with id being the templates UUID:
<Link to={`/templates/${id}`} {...itemProps} />
But when you click the link you go to /assets/correct-UUID.
I can't find any information on this so I'm not sure if this is the classic intermediate problem not covered by tutorials, something that isn't possible or I'm just doing something wrong. Does anyone know which one it is?
That defeats the purpose of the Switch and the router at the same time. From the docs:
Renders the first child <Route> or <Redirect> that matches the location.
Switch basically ensures there's only ever one component rendered in the router. For optimal results, keep your routes in one component, as there is rarely any need to nest them like you do. For example:
import { Switch, Route } from 'react-router'
<Switch>
<Route exact path="/" component={Main}/>
<Route path="/assets" component={Assets}/>
<Route path="/templates" component={Templates}/>
</Switch>
So you define your routes in your app entry point let's say App.js. And that's it, if you want more routes, add them there. If you want nested routes, you nest by literally nesting it: <Route path="/assets/:id/update" component={AssetUpdate} />. That's all there is to it.

React component breakdown strategy

I need to implement components tree on React.
And I'm wondering what is good enough pattern how to break everything in tree
but with scaling(code or team) in mind.
Usually I'm using next way:
function UserAvatar(props) {
return <div><img src="" alt="" /></div>
}
function UserEmail(props) {
return <div>e-mail: some#email.com</div>
}
function UserSection(props) {
return (
<div className="container">
<div className="section">
<UserAvatar />
</div>
<div className="section">
<UserEmail />
</div>
</div>
);
}
But should I avoid all this layout divs and make layout cleaner?
One obvious option is to move into the separate component layout stuff.
Thanks
Guidelines on breaking down components:
When your component is doing too much. Components should ideally be focused on doing one (or a few, but not many) things. The most obvious sign is when the number of lines in the code is getting too long. As a rough estimate, components should not be more than 300 lines.
When you want to reuse components across multiple parent components, you'll have to break them up.
If you want to optimize the render() of specific subtrees of a componant via shouldComponentUpdate(), then you have to break them up as you can only implement shouldComponentUpdate() on the component-level.
Separating data fetching logic from rendering and handling user interactions logic. Instead of making one component do both data fetching and (rendering and handling user interactions), break them down into smaller components so that you can test the components separately:
Test that the first component fetches data.
Test that the second component renders the data properly and can respond to user interactions.
Read more about it here
Many more good answers by Kent C. Dodds here.
It's a good practice to keep each Component in their own files then import them where you need to reference them.
Also, in your example it's most likely you'll need to set the avatar url and email as props. Then make the UserAvatar and UserEmail render the values. Also, it's good practice to setup the propTypes, so other developers (and yourself) know which props to pass.
One criteria to break down components into subcomponents it's when they deal with different concerns, or when the file size is getting too large. Another criteria is when you need to re-use that component in some other context.
Hope this helps.

ReactRouter route render component to container element

My issue here is that I need to render separate route components to elements created by the backend. It's irregular I'm sure. Essentially I'm starting with an html document and need to render route components to particular elements in the dom.
Example:
If I have four components that each need to be rendered to a pre-generated element.
<body>
<div id="elone" />
<div id="eltwo" />
<div id="elthree" />
<div id="elfour" />
</body>
Now I need to render my respective components to each of those elements. The issue is that if I call ReactDOM.render within the component it doesn't recognize the router, and it doesn't appear that route has anyway to render to a particular element.
Note: I cannot unfortunately write the document within the JS, it has to be pre-generated. I don't need this to be done through react router if there are other solutions, but the components must recognize the router.
I hate answering my own questions, it makes it seem like no one is really answering questions here.
Anyhow the solution is to use ReactDOM.createPortal instead of ReactDOM.render within the components. Make sure to render the component with the router to an element outside of the container that you want to portal your subcomponents to otherwise you'll obviously clobber the elements that your portals are pointing to.

React - remounting components on url change

So I am working on React/redux app with react-router v4.
Page structure is more or less this:
<html>
<head>...</head>
<body>
<aside>
<NavigationComponent />
</aside>
<main>
<ItemComponent />
</main>
</body>
</html>
So I pretty much render an <ItemComponent /> within main depending on the url the user is on, say either /11 or /231. The way I do this currently is use redux's mapStateToProps to retrieve item out of items by id, using react-router injected props, namely params. Then item is passed to as a prop and so the contents get rendered. However, prop changes, namely item changes, only trigger difference rerenders.
How would I accomplish unmounting current <ItemComponent /> and mounting a new one? Or better yet, what's the best way to animate this component, say when entering and leaving (triggered by url change)?
I managed to hack something around using ReactTransitionGroup addon, however I am interested in the cleanest way to accomplish this.
Thanks a lot!

Categories

Resources