Creating browser site history in React - javascript

I'm fairly new to React and I'd like to build a panel to show Recently Viewed URLs within my web site.
I'm trying to use the createBrowserHistory library to do that from a navigation page. Here is the layout:
└── navigation
├── component1
└── component2
└── component3
I'd like to implement something where if I click on component3, then component1, then component2, it would display something like this:
Recently Visited:
component2
component1
component3
I have a History.js file that consists of only this:
import { createBrowserHistory} from 'history';
export default createBrowserHistory({
})
and from the Navigation.js page, I have something like this:
import history from './path/to/History';
import { useLocation } from 'react-router-dom';
const location = useLocation();
history.push(location)
Now if I do a console.log(history), I just see the current path that I'm on, but not the previous URLs. I was under the impression that history.push() pushes the URL to a stack, but how do I extract the last several URLs that were visited?

You need to add the history as a property into the Router(router provider)
import React from "react";
import ReactDOM from "react-dom";
import { Router } from "react-router";
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
ReactDOM.render(
<Router history={history}>
<App />
</Router>,
node
);
And then your hooks would be work well as your expected

Related

How to use History object of react-router-dom (v6) in Redux

The React Router docs show that redirecting outside of react components is as follows.
import { createBrowserHistory } from "history";
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
const historyObject = createBrowserHistory({ window });
root.render(
<HistoryRouter history={historyObject}>
//your components and Routers ...
</HistoryRouter>);
And can use the history object in any non-react component function (in Redux)
function xyz(){
historyObject.replace('/');
//or
historyObject.push("/");
}
But just when the page is reloaded, an error occurs and nothing works, how can you use a redirect in Redux?
enter image description here

CSS Path in Reactjs is wrong

I have observed that suddenly CSS path in my project is changed, I am not sure about the reason whether this is a configuration issue or any other, but because of the path CSS is taking too much time to load.
I have already tried to check imports and everything in the code but it seems proper
Please check the below image for path comparison between the new and the backup folder.
New Path:
Old Path
Note: I need the path to be like old where react convert the css to inline, this runs faster.
Below is how I have imported my custom CSS in index.js:
import * as serviceWorker from './serviceWorker';
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { render } from 'react-dom';
import App from './App';
import './index.css';
import './utilities/animate.css';
//react and redux related library
import { Provider } from 'react-redux';
import store from './redux/store/index';
class Main extends Component {
render() {
return (
<Route path='/' component={App} />
);
}
}
let rootElement = document.getElementById('app');
render(<Provider store={store}>
<BrowserRouter >
<Main />
</BrowserRouter>
</Provider>, rootElement);
serviceWorker.unregister();
I have run npm update and updated few packages, may be some of the packages were corrupted or outdated. This fixed my issue of performance and CSS loading slow.

Jest testing component getting "TypeError: (0 , _reactRouter.withRouter) is not a function"

This is a whopper.
For some reason, jest and babel won't import and transpile react-router 4's withRouter.
I recently updated from react-router 3 to react-router 4. My single page app compiles via webpack just fine, and I can navigate my local dev version just fine in the browser.
However, tests that involve components that are wrapped with the withRouter HOC fail.
Specifically, if the component being tested has a descendant component that uses the withRouter HOC, you can't even import withRouter. A console log shows that withRouter is imported as "undefined"
The folder has the following files.
app/
├── src/
├── LoginContainer.jsx
├── LoginForm/
├── index.js
└── LoginForm.jsx
LoginContainer (A react container component)
import React from 'react';
import PropTypes from 'prop-types';
import LoginForm from './LoginForm';
export default class LoginContainer extends React.Component {
constructor(props) {
super(props);
this.state = { currentForm: props.form };
this.changeForm = this.changeForm.bind(this);
}
changeForm(form) {
// handle when someone changes something.
}
render() {
return (
<section>
<LoginForm {...this.props} changeForm={this.changeForm} data-form={this.state.currentForm} />
</section>
);
}
}
LoginForm/index.js (basically a HOC that wraps LoginForm.jsx)
import LoginForm from './LoginForm';
import { withRouter } from 'react-router';
// NO MATTER WHAT I DO...
// withRouter is undefined.
// If I do import * as bob from 'react-router'
// bob then equals { default: {} }
// bob is blank!
export default withRouter(LoginForm);
For some reason, I can't import withRouter when testing. All other modules import just fine, only withRouter is causing issues.
react-router 4.2.0 and react-router-dom 4.2.2 are both installed as dependencies
Other components that use things like Link or Route pass tests just fine
UPDATE
I think it has to do with jest + babel. If I switch the import statement to a require statement, it works!
import LoginForm from './LoginForm';
// THIS WORKS! But I don't want to deviate from ES6 just for a test.
const withRouter = require('react-router/index.js').withRouter;
export default withRouter(LoginForm);

How To export all stores in mobx using single index.jsx?

I have the following file structure for stores:
user.jsx
notification.jsx
subscriber.jsx
Each exporting a default store. I want to create a single file index.jsx so that I can call them as required using a single file.
In redux the functionality can be achieved using combineReducers function.
Does mobx has similar option? If no then how can I achieve it?
You could e.g. create an index.jsx file in your store directory:
// stores/index.jsx
import user from './user.jsx';
import notification from './notification.jsx';
import subscriber from './subscriber.jsx';
const stores = {
user,
notification,
subscriber
};
export default stores;
Then you can use this to e.g. inject all the stores into a Provider:
// app.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react';
import stores from './stores';
ReactDOM.render(
<Provider {...stores}>
{/* ... */}
</Provider>
document.getElementById('app')
);

React, Electron, And Router

I am currently to adapt a simple web app i made (using React and Redux) into a native desktop app.
I am using GitHub's Electron and Webpack to do this. Everything is fine if I use hashHistory from React-Router.. but I want to use browserHistory so my app will still look nice (URL-wise) when running as a webapp. If i do this though, I get the following error:
No route matches path ".../index.html"
Which makes sense to me. I am loading index.html as the main file for Electron:
mainWindow.loadURL('file://' + __dirname + '/index.html');
I'm just wondering if it is at all possible to use browserHistory with React-Router and Electron. If anyone knows it would be greatly appreciated!
Not exactly. But there is even better solution .
You should Separate from your react app the bootstrap file.
Bootstrap file which load your app and pass to it some additional params from outside.
In your situation you will create two bootstrap files, one for electron - with memoryHistory (I think it is better for electron) and second one for browsers with browser history.
Example of bootstrap file for electron index-electron.jsx:
import React from "react";
import ReactDOM from "react-dom";
import { createMemoryHistory } from "react-router";
import App from "./App.jsx";
const initialState = window.__INITIAL_STATE__;
const config = window.__CONFIG__;
const history = createMemoryHistory("begin-path");
ReactDOM.render(
<App
config={config}
history={history}
initialState={initialState}
/>, document.getElementById("root"));
Example of bootstrap file for browsers index-browser.jsx:
import React from "react";
import ReactDOM from "react-dom";
import { browserHistory } from 'react-router';
import App from "./App.jsx";
const initialState = window.__INITIAL_STATE__;
const config = window.__CONFIG__;
ReactDOM.render(
<App
config={config}
history={history}
initialState={initialState}
/>, document.getElementById("root"));
In my examples difference is small (only history) but you can make more changes. As you see I also provide additional begin params from outside (initialState, config);
And how your App should :
import React from 'react';
import { Router, Route } from 'react-router';
class App extends React.Component {
static propsTypes = {
history: React.PropTypes.object,
config: React.PropTypes.object,
initialState: React.PropTypes.object
};
render() {
return (
<Router history={this.props.history}>
<Route ...>
...
</Route>
</Router>
);
}
}
export default App;
Above code is only conception. It is from my project, where I removed obsolete things. Therefore without some modification it may not work
Now for electron you use index-electron.jsx, and for browsers index-browser.jsx. Most of your code is reusable cross both envs. And it is very flexible.

Categories

Resources