Importance of react-router-redux push - reactjs

I am using react-router-redux push in my project but not sure why my team is using it in actionsToProps. Is there any special benefit out of it?
push in actionsToProps works fine
import {push} from 'react-router-redux';
const actionsToProps = {
registerUser: actions.registerUser,
push
}
export default connect(mapStateToProps, actionsToProps)(Register);
The reason I am asking this question because my component still works fine without push.
without push in actionsToProps works fine too
import {push} from 'react-router-redux';
const actionsToProps = {
registerUser: actions.registerUser
}
export default connect(mapStateToProps, actionsToProps)(Register);
Would request you to clarify if my question doesn't looks like stupid.

According to the documentation, push "Pushes a new location to history, becoming the current location". IE. it is used to change/ open pages via react-router. It is meant as an alternate of react-router.
You can use it like:
store.dispatch(push('/foo'))

Related

Typescript npm library can't export Redux store please advice

I use the Notistack library and forked it and then using VSCode to try to add a Redux store in the library that I want to expose to Apps.
I'm not so good with Typescript. I have some trouble hehe.
What I want to do is that when the app is using Notistack to show a snack message. I want to use Redux to update the message in real time, like a file up/download progress showing on the snack. It's here Notistack new Redux store(that i create here) come into play. I want Notistack to expose the Redux store to the app so the app can send redux dispatch into to Notistack Redux Store. and showing dispatched message in the Notistack SnackbarItem.tsx
(hope you understand)
When I compile in VSCode I get this error in my app:
Failed to compile.
./src/redux/root-reducer.js
Attempted import error: 'notistack' does not contain a default export (imported as 'NotisReducer').
My root-reducer in the App look like this:
import { combineReducers } from 'redux';
import NotisReducer from 'notistack';
import snackReducer from './snackbar/snack.reducer';
const rootReducer = combineReducers({
snack: snackReducer,
NotisReducer,
});
export default rootReducer;
As you see I import Notistack's NotisReducer and I think I have implemented that.
(I have used NPM link to add locally forked Notistack library into my app)
Now it looks like this here is Notistack's indext.js file where I expose Redux store as NotisReducer:
What I did in Notistack was I added a to index.d.ts:
I define the type store like this:
import * as React from 'react';
import { SnackbarClassKey } from '#material-ui/core/Snackbar';
import { ClickAwayListenerProps } from '#material-ui/core/ClickAwayListener';
import { TransitionProps } from '#material-ui/core/transitions/transition';
import { StandardProps } from '#material-ui/core';
import store from './Redux/store'; // MY STORE
...
...
export type store = store; // EXPORT IT
I'm not sure if this is correct as I could not set breakpoint in npm linked Notistack. Maybe it's to many problem now that must be fixed first.
In the file
SnackbarProvider.tsx
I did like this, importing the store type from index.d.ts):
import {
SnackbarProviderProps,
SnackbarKey,
SnackbarMessage,
OptionsObject,
RequiredBy,
ProviderContext,
TransitionHandlerProps,
store, // STORE
} from ".";
import createChainedFunction from "./utils/createChainedFunction";
export { store }; // EXPOSING IT
In the file
NotisReducer.js
I import the store to be sent to indext.js above
But as you saw above I get compiler error store is not exported.
Attempted import error: 'notistack' does not contain a default ex (imported as 'NotisReducer').
please advice :))

Resolve a React Native/Web Common import problem

Merry Chrismas...
I got a React project structured like below
- My project
|- common (redux and redux-persist installed)
|- mobile (... with react-native init)
|- web (... with create react app)
I tried then to import a basic redux from common in mobile and got an error
Here's the code
import default_storage from "redux-persist/lib/storage"
import default_storage from "redux-persist/lib/storage";
import thunk from "redux-thunk";
...
export default (storage = default_storage) => {
const store = createStore(
combineReducers({
auth: persistReducer(
{ key: "auth", storage},
authReducer
),
event: eventReducer,
}),
applyMiddleware(thunk)
);
return store
};
...
When I try to call the function in mobile passing AsyncStorage as parameter
I got an error saying the function couldn't compile because of the fact that there's no part of common that can compile the native part of AsyncStorage.
I tried first with adding fields resolve in babel.config.js but it actually doesn't work
If someone already did this kinda Structure before, would you share ya code please. Just how to structure the code
Thanks guys

react redux: private route not rendering layout

Code Sandbox link:
and trying to follow this article
On successful login(/auth/login), the user should be routed to the dashboard(/admin/summary). If the login is successful, I am also storing an access token.
I have a PrivateRoute component for this. The problem is that on successful login, the URL is getting updated but the component is not getting rendered.
PS: about the dashboard, this is a single page application so, the dashboard has topbar, sidebar, and the right content and altogether these things are coupled inside <AdminLayout/>. So, in my AppRouter, I have to render the <AdminLayout/> and just any one component.
All the react and redux code is included in the code sandbox.
Since in your code you create your own history object (it happens in you history.js file, when you call createBrowserHistory()) but doesn't pass it to your Router, nothing happens.
There are 2 possible solutions:
1. Don't create a history object yourself, but use useHistory hook inside your component
Working Demo
With this approach, you should remove history.push from login.actions.js (which imports history) and use history.push in Login.js (which uses useHistory hook):
// login.actions.js
...
loginService.login(userid, password, rememberPassword).then(
(userid) => {
dispatch(success(userid, password, rememberPassword));
// history.push(from); <-- commented out!
},
(error) => { ... }
);
};
...
// Login.js
function handleSubmit(e) {
...
const { from } = {
from: { pathname: "/admin/summary" }
};
history.push(from) // <-- added!
dispatch(loginActions.login(inputs, from));
...
}
useHistory exposes the history object of BrowserRouter (I think this is implied in this official blog post).
2. Create a history object yourself, but pass it to a Router component
Working Demo
This approach would require you to make several changes:
Creating the history object on your own means you become responsible to provide it to a router component, but it can't be a BrowserRouter, but the base Router component (see these Github answers: 1, 2).
Once you import Router (instead of BrowserRouter), you need to get rid of any useLocation and useHistory imports, otherwise you'll get errors.
I also had to unify the history object export and imports, so that it is exported as the default export (i.e., export default history), and it is imported as the default import (i.e., import history from "./history"; instead of import { history } from "./history")
(P.S: this approach can be seen implemented elsewhere on SO, for example here or here (the latter explicitly installs history, but it's not needed in your case).

Importing redux action makes other actions undefined

This is one of the strangest things I have ever seen. It makes absolutely no sense to me. The short version is I have a Redux action creator function. If I import this function into this one particular component file, it makes every function imported from its file undefined.
So, let's start with the file filterInputModal.actions.js. This contains my Redux action functions, created using redux-starter-kit:
export const showAddCategoryModal = createAction('showAddCategoryModal');
That is the function I've been working with. Now, this function has long since been imported into my ManageVideoFilters.js component:
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { showAddCategoryModal } from 'store/filterInputModal/filterInputModal.actions';
const ManageVideoFilters = (props) => {
/* Component logic */
};
/* PropTypes and mapStateToProps */
const mapDispatchToProps = (dispatch) => bindActionCreators({
showAddCategoryModal: () => showAddCategoryModal() // Done this way to avoid passing in a payload, since certain default event payloads cause Redux to print console errors
});
export default connect(mapStateToProps, mapDispatchToProps)(ManageVideoFilters);
So far so good. Before we go and break everything, let's take a look at my filterInputModal.reducer.js Redux reducer, also created using Redux Starter Kit:
import { createReducer } from 'redux-starter-kit';
import { showAddCategoryModal } from './filterInputModal.actions';
const initialState = {}; // The initial state for the reducer goes here
const handleShowAddCategoryModal = (state) => {
/* handle updating the state */
return state;
};
const actionMap = {
[showAddCategoryModal]: handleShowAddCategoryModal
};
export default createReducer(initialState, actionMap);
The action map uses the action creator functions toString() as the key, and then I provide my own functions to handle updating the state. Again, at this point, everything is perfect. We will come back to the reducer in a sec, first let's break things.
Now we're going to my VideFileEdit.js component. If we add the following line to this component, everything breaks:
import { showAddCategoryModal } from 'store/filterInputModal/filterInputModal.actions';
So, how does it break?
The import of the showAddCategoryModal function in filterInputModal.reducer.js now is undefined.
Because the reducer is using the functions as the keys to handle actions, the reducer is no longer able to handle the action properly and update the state.
It gets weirder though. Here are some of the weird behaviors I'm seeing.
If I import this action into any other component, everything is fine. The import in the reducer is unchanged.
The import of the function in both ManageVideoFilters.js and VideoFileEdit.js is fine.
So, what can I try next? This is really strange and doesn't make any sense to me. I've never seen this before.
As the commenter said, the problem was recursive imports. My filterInputModal.reducer.js exported some constants, which were imported into my filterInputModal.actions.js. The actions from filterInputModal.actions.js were then imported into filterInputModal.reducer.js. Hence the recursive import.
I moved the constants into a new file, filterInputModal.constants.js, and viola, problem solved.

Trouble adding authentication with React and Firebase

I'm having issues adding authentication to an app I have been working on.
Everything works fine with firebase as-is without the auth, until I start adding these new lines, which are basically just:
export const provider = new firebase.auth.GoogleAuthProvider();
export const auth = firebase.auth();
import firebase, { auth, provider } from './firebase.js';
I have a file for my config (config.js), which just contains an export for DB_CONFIG (with all my correct info). Here's where I'm running into issues. The tutorial I'm following has firebase imported and initialized in the config file, while I am doing so in my App.js file. I've been trying different things for a couple hours and nothing is working for me. If I import firebase into my config and initializeApp there, it breaks my App.js. Here's a gist of my code vs. what I'm trying to follow.
Is there an easy way to get the auth and provider set up and imported into my App.js file without changing too much?
After looking at your code I made some changes to it, maybe this approach help?
import * as firebase from 'firebase'
import { DB_CONFIG } from './Config/config';
// Configure firebase and it will be available globally.
firebase.initializeApp(DB_CONFIG)
// Once initialized you just need to create the provider and auth
const provider = new firebase.auth.GoogleAuthProvider();
const auth = firebase.auth();
class App extends Component {
constructor(props){
super(props);
// And just call firebase.database() to access database functionality.
// You don't even need to assign it to a local variable as you can access
// it anywhere in your code just by importing firebase
// and calling firebase.database() and also firebase.auth()
this.databaseRef = firebase.database().ref().child('players');
}
}
PS: I would delete your gist because, even though you changed the config file, your configuration info is still available in the gist revisions...

Resources