问题
All around it but not quite as I have enough of an idea of redux-thunk
and of react-router
but I am not getting this seemingly simple idea of:
Call a change in route programmatically via <Route/>
's history.push('/')
after an action has finished dispatching to the store, this to happen when a button is pushed.
const LoggerRedux = ({stateProp, LogIn}) => {
return(
<div>
<h2>Here is the button. Use this to login</h2>
<Route render={({ history}) => (
<button
type='button'
onClick={
//Something that calls {LogIn}
//and then the history.push('/')
}
>
Log yo Arse Inn
</button>
)}>
</Route>
</div>
)
}
const mapStateToProps = (state) => {
return {
stateProp : state
}
}
const mapDispatchToProps = (dispatch) => {
return {
LogIn : () => dispatch({
type : 'AUTHENTICATE'
}),
LogOut : (bool) => dispatch({
type : 'LOGGED_OUT',
bool
})
}
}
const LoginConn = connect( mapStateToProps, mapDispatchToProps)(LoggerRedux);
Layman explanations and examples of all things I mentioned/tagged would also be nice
回答1:
Have your action creator return a promise. This way when you invoke it, you can use .then() and in your then handler you can push a new address to the history.
Thunks will return functions normally, but a promise differs in that you can act after completion.
Example:
static myActionCreator(somevar) {
return dispatch => {
return new Promise((resolve, reject) => {
dispatch({
type: "myaction",
something: somevar
});
resolve()
});
}
}
So in this case, your thunk returns a promise. Then when you invoke like this:
this.props.myActionCreator(somevar)
.then(() => {
this.props.history.push('/winning')
})
This thunk is just dispatching an action, but you could have some async call in there that has a callback, etc. and you resolve on completion.
回答2:
I had similar confusion and ended up spending quite a time working on solving the problem through callbacks and javascript promises which is not required at all because of react-redux setup.
this.props.clearReducersState()
this.props.history.push('/dashboard')
I was trying to go to my dashboard after my clearReducerState() function is dispatched. This code works just fine.
You need to do nothing react-redux works on a synchronous way, so you can simply do this. You can use history.push in your action too for that,
import { withRouter } from 'react-router-dom';
this.props.clearReducersState(this.props.history)
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(UpdateAid))
And in your action,
export const clearReducersState = (history) => dispatch => {
history.push('/dashboard')
}
However, if you are updating your state using reducers it is better to use history.push in your index file to avoid problems.
Use as per your requirement. Hope this helps.
回答3:
I want to highlight this section here...
<Route render={({ history}) => (
<button
type='button'
onClick={
//Something that calls {LogIn}
//and then the history.push('/')
}
>
Log yo Arse Inn
</button>
)}>
</Route>
You want to call Login and push the history to the root of the application. You have a couple options here:
call the function
history.push('/')
within your Login function, this looks to be within your reducerAUTHENTICATE
function.dispatch an action that calls
history.push
after successful authentication look atredux-promise
orredux-saga
,redux-thunk
is a bit trickier to do, but its possible
I wouldn't try to do it any other way for the moment as you're dependant on login (which is called via redux, so I'd want to keep the logic in there, even though it's a client-side redirect).
回答4:
According to this stackoverflow answer: Is store.dispatch in Redux synchronous or asynchronous, redux dispatch functions are synchronous therefore, you can do this:
LogIn();
history.push("/");
来源:https://stackoverflow.com/questions/47565389/call-function-after-dispatch-from-redux-has-finished