Any way to get current params outside a component - reactjs

Is it possible to get the params outside of a component props?
In my case I want handle navigation inside some action creators (with redux).

Let's say that you connected the action createUser to your component ok?
So from your component you are going to do this:
this.props.createUser(this.props.username, this.props.password)
And finally this is going to be your action dispatcher:
export const createUser = (username, password) => {
return (dispatch,getState) => {
dispatch({
type: CREATE_USER,
username: username
})
browserHistory.push(`/welcome-user/${username}`)
}
}

Related

What is the best way to redirect to another page after successful action in Redux?

I'm trying to redirecting user after they successfully logged in by dispatching "AUTH_SUCCESS" action and gave me their tokens.There are several ways of doing this but I want your advise.Which one is the best way to redirect them after login? Whether using something in actions or in functional components.NOTE: I'm using functional components. Thanks!
Pseudocode
For thunk just pass this.props.history in your login event
Front end somewhere..
login = (e) => {
e.preventDefault();
const creds = { username: username, password: password}
this.props.login(creds, this.props.history);
}
Thunk
export const login = (credentials, history) => {
return (dispatch) => {
.....
/// after successful
history.push('/dashboard);
}
}

React-redux: actions with variables

so i've this action:
export const getMovieDettails = (id) => (dispatch) => {
dispatch({type: GET_MOVIE_DETTAIL_LOADING})
fetch(`api/movieId/${id}`)
.then(response => response.json())
.then(movie => dispatch({type: GET_MOVIE_DETTAIL_LOADED, payload: movie}))
.catch(err => dispatch({type: GET_MOVIE_DETTAIL_FAIL, payload: "Error with API"}));
}
on App.js i do this:
const mapDispatchToProps = (dispatch) => {
return {
onGetShows: () => dispatch(getHomeShows()),
onGetMovies: () => dispatch(getMoviesShows()),
onGetSeries: () => dispatch(getSeriesShows()),
onGetMovieDettail: (id) => dispatch(getMovieDettails(id))
}
}
and then pass the function to
<Route path="/movie/:id" render={(routeProps) => <MovieDettailsRouter key={routeProps.match.params.id} data={this.props.movieDettail} movieDettail={this.props.onGetMovieDettail} {...routeProps}/>}/>
so on MovieDettailRouter i do
componentDidMount() {
console.log(this.props.match.params.id);
this.props.movieDettail(this.props.match.params.id);
}
but not work, how can pass the function with paramaters, for good experience i call all state and actions on App.js and then pass data on the component, for call without paramaters i don't have problems, everything it's fine, but here where i need to get the params for the actions 've problem, on v1 of App i don't use actions for this page, i use only for page without actions with params, but on this update i decide to use redux for every call on server and i need to understan how can pass an actions with params on components
Edit: Add the state on MovieDettailRoute
You don't seem to be passing the state to the MovieDetailsRouter component.
After the data is fetched, dispatched and the store changes all the components that are listening for that part of the store will update.
The component needs to have access to the state to get the data.
You can pass the data to the component by getting the part of the state that your action will update with mapStateToProps in the App component, and then pass it to the MovieDetailRouter

How to get the value as props in a different component

In my react application, I have three parallel components. In my first component, I am doing an API call and based on the response I am routing the flow to Validated or Non-Validated Component.
Once the user is routed to validated component, there is a button on click of which user should be redirected to another component which should display the data in API response (first component) as key value pair. I am using Redux for state management.
The issue I am facing is the data is dispatched as an empty object from the store. I am not sure where I am going wrong but when I am debugging the app, I see the the action is not getting dispatched to the store and it's always returning me the initial state.
action.js-
export const setPoiData = (poiData) => dispatch => {
console.log('inside actions');
dispatch({
type: SET_POI_DATA,
payload: poiData
})
}
Reducer.js-
const initialState = {
poiData: {},
}
const reducerFunc = (state = initialState, action) => {
switch (action.type) {
case SET_POI_DATA:
console.log('inside poi reducers');
return {...state,poiData: action.payload}
default: return {...state}
}
}
Component 1-
//API call
Detail Component-
To get the data from store I am doing something like below-
componentDidMount() {
console.log(this.props.poiData)
}
function mapStateToProps(state) {
return {
poiData: state.poiData,
}
}
const mapDispatchToProps = dispatch => ({
setPoiData(data) {
dispatch(setPoiData(data));
}
})
I am not sure where I am going wrong. Can someone suggest me how to proceed ahead on this?
inside componentDidMount() you must call action like this this.props.setPoiData(<your data here>);

React Redux best practices for performing actions

Where should I perform actions (redirecting or adding/removing something to/in the localstorage) in React (and Redux)? So after the password is successfully updated I want to redirect the user to another page. Should I redirect after the dispatch method, should I do it in the component or are there other options?
Example action:
export function updateAccountPassword(encryptedPassword) {
return dispatch => {
axios.post(API_URL + '/account/recovery/update', {
_id: getSignedInUserID(),
password: encryptedPassword
}).then(() => {
dispatch(updateUserPasswordSuccess())
}).catch(() => {
dispatch(updateUserPasswordFailError());
})
}
}
function updateUserPasswordSuccess() {
return({
type: RECOVERY_UPDATE_SUCCESS
})
}
function updateUserPasswordFailError() {
return({
type: RECOVERY_UPDATE_FAIL_ERROR,
payload: 'Something went wrong, please try again'
})
}
The way I am doing it is by passing the this.props.history.push as a callback to the action creator, and calling it, as you suggested, in the action creator, after dispatch.
Here is an example from my code:
In the component form's submission, calling the action creator:
this.props.ACTION_CREATOR(formPayload, () => {
this.props.history.push(`ROUTING_TARGET`);
});
And, then, in the action creator, when the proper condition has been met, calling the callback (rerouting).

React-redux get props or state in mapDispatchToProps

please excuse potentially noob question, am new to react and react-redux.
I have a component representing a login screen currently. One of its props is "login", a dictionary that contains the email and password. After defining the component, I use the react-redux library to connect it with the store like so:
const mapStateToProps = (state) => {
return {
rootNav: state.rootNav,
login: state.login,
};
};
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onLoginClick: () => {
// TODO: actually get the login credentials from the view
dispatch(actions.submitLogin('testuser', 'testpw'));
dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
},
onEmailUpdate: (email) => dispatch(actions.updateEmail(email)),
onPasswordUpdate: (password) => dispatch(actions.updatePassword(password)),
};
};
Obviously, in the line dispatch(actions.submitLogin('testuser', 'testpw')); I want to have the real email and password submitted as a payload with the action. But I don't understand how I should be accessing it from the component (i.e. I can't just use this.props.login) or if/how I should be accessing it from the store (where would I pass the store in?)
Any clarification would be extremely helpful!
I think this can be handled in two ways. mapDispatchToProps is passed as the second argument to the react-redux connect function. It gives the connected component access to certain action creators. In this case you're giving it the action creators onLoginClick, onEmailUpdate, and onPAsswordUpdate.
Those functions are now accessible in your component via this.props.onLoginClick, this.props.onEmailUpdate etc. An easy solution is to create an onClick event on your login button, or onSubmit of the login form. If you're updating your Email and Password on your redux state and passing them to this component as props you can do something like this:
In your login class:
login() {
// get password and email from the props
const pw = this.props.password;
const email = this.props.email;
// submit login action with email and password
this.props.onLoginClick(email, password)
}
render() {
<form onSubmit={this.login.bind(this)}>
...
</form>
}
And update mapDispatchToProps to have onLoginClick expect an email and password.
const mapDispatchToProps = (dispatch, ownProps) => {
return {
// update this action creator to take an email and password
onLoginClick: (email, password) => {
// TODO: actually get the login credentials from the view
dispatch(actions.submitLogin(email, password));
dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
},
onEmailUpdate: (email) => dispatch(actions.updateEmail(email)),
onPasswordUpdate: (password) => dispatch(actions.updatePassword(password)),
};
Option 2
Otherwise according to the react-redux docs here https://github.com/reactjs/react-redux/blob/master/docs/api.md you can also use the second argument of mapDispatchToProps, ownProps.
So you can change onLoginClick to look like this:
onLoginClick: () => {
const email = ownProps.email;
const password = ownProps.password;
dispatch(actions.submitLogin(email, password));
dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
}
and on your form you can do this:
render() {
<form onSubmit={this.props.onLoginClick}>
...
</form>
}
or if you want it to be only on a button click...
<button onClick={this.props.onLoginClick}>Login</button>

Resources