从 redux 分派完成后调用函数

Call function after dispatch from redux has finished

围绕着它,但不完全是因为我对 redux-thunkreact-router 有足够的想法,但我没有得到这个看似简单的想法:

在动作完成发送到商店后,通过 <Route/>history.push('/') 以编程方式调用路由更改,这在按下按钮时发生。

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);

通俗易懂的解释和例子我mentioned/tagged也很好

我想在此处突出显示此部分...

<Route render={({ history}) => (
  <button
    type='button'
    onClick={

    //Something that calls {LogIn}
    //and then the history.push('/')

    }
    >
    Log yo Arse Inn
  </button>
)}>

</Route>

您想调用登录​​并将历史记录推送到应用程序的根目录。 您在这里有几个选择:

  1. 在您的 Login 函数中调用函数 history.push('/'),这看起来是在您的 reducer AUTHENTICATE 函数中。

  2. 在成功验证后调度调用 history.push 的操作 看看redux-promiseredux-sagaredux-thunk做起来有点棘手,但有可能

我暂时不会尝试以任何其他方式来做,因为你依赖于登录(这是通过 redux 调用的,所以我想保留那里的逻辑,即使它是一个客户端-端重定向)。

根据这个 Whosebug 的回答:,redux 调度函数是同步的,因此,你可以这样做:

LogIn();
history.push("/");

让你的动作创作者 return 一个承诺。这样当你调用它时,你可以使用 .then() 并且在你的 then 处理程序中你可以将一个新地址推送到历史记录中。

Thunks 将 return 正常运行,但 promise 的不同之处在于您可以在完成后采取行动。

示例:

static myActionCreator(somevar) {
  return dispatch => {
    return new Promise((resolve, reject) => {
      dispatch({
        type: "myaction",
        something: somevar
      });

      resolve()
    });
  }
}

因此,在这种情况下,您的重击 return 是一个承诺。然后当你这样调用时:

this.props.myActionCreator(somevar)
.then(() => {
  this.props.history.push('/winning')
})

这个 thunk 只是在调度一个动作,但你可以在那里进行一些异步调用,它有一个回调等,你在完成时解决。

我也有类似的困惑,最后花了很多时间通过回调和 javascript promises 来解决问题,因为 react-redux 设置,这根本不需要。

this.props.clearReducersState()
this.props.history.push('/dashboard')

我试图在调度 clearReducerState() 函数后转到我的仪表板。 这段代码工作得很好。

你什么都不用做 react-redux 以同步方式工作,所以你可以简单地这样做。 为此,您也可以在操作中使用 history.push,

import { withRouter } from 'react-router-dom';
this.props.clearReducersState(this.props.history)

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(UpdateAid))

在你的行动中,

export const clearReducersState = (history) => dispatch => {
history.push('/dashboard')
}

但是,如果您使用 reducer 更新状态,最好在索引文件中使用 history.push 以避免出现问题。

根据您的要求使用。 希望这有帮助。

我想你要找的是 Redux Saga.

您可以使用TakeEvery效果,每次调用特定操作时都会触发您想要的功能。

示例:

import { takeEvery } from `redux-saga/effects`

function* fetchUser(action) {
  ...
}

function* watchFetchUser() {
  yield takeEvery('USER_REQUESTED', fetchUser)
}

看看 doc 和 阅读此 article

official Redux tutorials.

建议我使用另一种方式

向您的状态添加一个枚举 status,以及一个变量 error = null

然后您可以为他们分配各种类型的状态。 你的情况

status = "idle" | "pending" | "failed" | "loggedin" | "loggedout";

然后在你的叫声中,

if (login succeeds)
   status = 'loggedin';
else {
    status = 'failed';
    error = 'e.message if you are using try catch';
}

在你的功能组件中,

const {status,error} = useSelector(state => ({state.status,state.error}));
const dispatch = useDispatch();
useEffect(()=>{
    if(status === "loggedin") 
         // don't forget to reset the status
         dispatch(setStatus('idle'));
         history.push('/dashboard');
    if(status === "failed")
        dispatch(setStatus('idle'));
        console.log(error);
},[status]);