How to use Redux Form Wizard with permanent URLS per page - reactjs

I'm working to build a signup > profile setup flow for a new application which is using React + Redux.
I found the following example for a redux form wizard:
http://redux-form.com/6.7.0/examples/wizard/
This seems to be the closest example but the problem is each step in the wizard does not change the URL, so if the user clicks the browser's forward/back btn or refreshes their browser, it will break.
Would it be OK to make Redux form wizard have permanent URLs? How can I approach this as a beginner?
Something where the wizard has URLs like:
/wizard/name
/wizard/profile
/wizard/photo

Would it be OK to make Redux form wizard have permanent URLs?
The way how it's implemented depends on every use case. I don't see any problem why it wouldn't be ok.
The wizard example tells you everything you need to know regarding your approach.
Talking about the official example, you could approach this in the following way:
Create a /wizard/name route which would render the same WizardForm.js component;
If the subpath is /name, render the WizardFormFirstPage
Same for the other subpaths.

I recently implemented a redux-form wizard with client-side routing. I will share some of the details here for posterity...
I have a component called MainContent which has several React-Router 4 routes. One of these routes looks like this:
<Route path={'/profile/:profileSection'} component={Profile} />.
This route loads a "wizard" style redux-form that the user fills out to set up her profile.
Note the profileSection route parameter. If the current URL is:
https://www.myawesomeapp.com/profile/my-age, the Profile component will receive a profileSection prop from the router with a (string) value of 'my-age'. This would be used to load the form "step" that asks the user her age.
Profile is a stateful component. Its render method returns the wrapped components for each step. It looks roughly this like this:
return (
<div>
<Step1 {...this.state} {...this.props} />
<Step2 {...this.state} {...this.props} />
<Step3 {...this.state} {...this.props} />
</div>
)
}
The profileSection router prop gets passed into each of the "step" components. These step components are created from an HOC. The HOC decorates each component with the following behavior:
Match a regular expression against the profileSection prop.
If it matches, the component's render method returns the markup for said step.
if it does not match, the component's render method returns null.

Related

How to listen to route changes in react router v5?

I need to throw out a warning when I try to go to another page or endpoint if the document is not saved
There's a declarative approach of how one can prevent navigation using <Prompt> component.
<Prompt
when={isBlocking}
message={location =>
`Are you sure you want to go to ${location.pathname}`
}
/>
isBlocking usually comes from the state of a component that needs to be conditionally rendered.
You can see a working example here.

How to use React Router to route to another url AND re-render page with NEW component?

In App.js, I have a button that if you click, should redirect users using React-Route to another URL, /landingpagehahaha, and should render a component called LandingPage. However, neither the URL is being changed in my browser nor the correct component being rendered. The behavior right now when you click the button is that the current page gets re-rendered, not the correct LandingPage component.
The React-Route logic is placed in a function called routeChange(). I put 2 alert() statements in it which get called, telling me that it is getting inside that function. However, nothing else changes.
I have tried using this.props.history.push("./LandingPage"); in routeChange() but it doesn't get past that statement. It appears like it behaves like response.json(), which returns from the function after it runs.
I have also tried using withRouter(), but I get a weird error that I can't call Route inside Router. I was unable to resolve that issue.
// Changes route
routeChange() {
alert("HELLO BEFORE");
alert("HELLo");
return (
<div>
<Route path="/landingpagehahaha" component={LandingPage} />;
</div>
);
}
// The button that is supposed to bring user to next page
<button onClick={this.routeChange}>Go To Next Page</button>
You need to return the Redirect component from your render function, or as use the history api to push the route into your navigation stack.
The first thing you should do, is move out the route declaration, and play it higher up in your component hierachy, you have to make sure the route declaration is rendered, when you're trying to go to the route.
Instead of using the history api, you could also use the Redirect component provided by react-router. I've made a small example here.
https://codesandbox.io/s/bold-paper-kxcri

React pagination without backend

I have the following Parent Component that contains several Child components:
class Parent extends React.Component {
render() {
<div>
<Child id='1'/>
<Child id='2'/>
<Child id='3'/>
<Child id='4'/>
<Child id='5'/>
<Child id='6'/>
<Child id='7'/>
<Child id='8'/>
</div>
}
}
I want to have pagination in the Parent class that shows maximum 3 Child components per 'page'. Is there a way to do that without a complex backend integration?
Here's a small demo which shows how you can accomplish something like that. It works by keeping a single variable in state for the current page being viewed, and rendering elements conditionally depending on whichever is the current page. You can add onto this with individual links that set the page directly, or whatever you prefer.
For anything more complex, look into routing, which is the concept of syncing your app state to the URL bar, to enable the user to use back/forward buttons in the browser for navigation. React Router is one of many libraries that can be used to accomplish this.
use a state variable like current_page_no which you can update from buttons like prev, next. Then just display 3 children starting at current_page_no*3.

Does React have keep-alive like Vue js?

I made a Todo list with React js. This web has List and Detail pages.
There is a list and 1 list has 10 items. When user scroll bottom, next page data will be loaded.
user click 40th item -> watch detail page (react-router) -> click back button
The main page scroll top of the page and get 1st page data again.
How to restore scroll position and datas without Ajax call?
When I used Vue js, i’ve used 'keep-alive' element.
Help me. Thank you :)
If you are working with react-router
Component can not be cached while going forward or back which lead to losing data and interaction while using Route
Component would be unmounted when Route was unmatched
After reading source code of Route we found that using children prop as a function could help to control rendering behavior.
Hiding instead of Removing would fix this issue.
I am already fixed it with my tools react-router-cache-route
Usage
Replace <Route> with <CacheRoute>
Replace <Switch> with <CacheSwitch>
If you want real <KeepAlive /> for React
I have my implementation react-activation
Online Demo
Usage
import KeepAlive, { AliveScope } from 'react-activation'
function App() {
const [show, setShow] = useState(true)
return (
<AliveScope>
<button onClick={() => setShow(show => !show)}>Toggle</button>
{show && (
<KeepAlive>
<Test />
</KeepAlive>
)}
</AliveScope>
)
}
The implementation principle is easy to say.
Because React will unload components that are in the intrinsic component hierarchy, we need to extract the components in <KeepAlive>, that is, their children props, and render them into a component that will not be unloaded.
Until now the awnser is no unfortunately. But there's a issue about it in React repository: https://github.com/facebook/react/issues/12039
keep-alive is really nice. Generally, if you want to preserve state, you look at using a Flux (Redux lib) design pattern to store your data in a global store. You can even add this to a single component use case and not use it anywhere else if you wish.
If you need to keep the component around you can look at hoisting the component up and adding a "display: none" style to the component there. This will preserve the Node and thus the component state along with it.
Worth noting also is the "key" field helps the React engine figure out what tree should be unmounted and what should be kept. If you have the same component and want to preserve its state across multiple usages, maintain the key value. Conversely, if you want to ensure an unmount, just change the key value.
While searching for the same, I found this library, which is said to be doing the same. Have not used though - https://www.npmjs.com/package/react-keep-alive

How to access value of a routing parameter in react?

I want to have a 'dynamic route' for a section of my app, which was done like this:
<Route path="path(/:id)" component={Component} />
So far this works, but in Component I would like to access the value of id because it changes a bunch of things depending on which it is. How can I do that?
In your component, you would access this via props.
this.props.params.id
Here is the guide from react-router that goes into more detail as well.
https://github.com/reactjs/react-router-tutorial/tree/master/lessons/06-params

Resources