React history.push() 不渲染新组件 [英] React history.push() not rendering new component

查看:68
本文介绍了React history.push() 不渲染新组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有简单登录功能的 React.js 项目.用户获得授权后,我调用 history.push 方法更改地址栏中的链接但不呈现新组件.(我使用 BrowserRouter)

I have a React.js project with a simple sign in function. After the user is authorized, I call history.push method which changes the link in the address bar but does not render the new component. (I use BrowserRouter)

我的index.js 组件:

ReactDOM.render(
  <Provider store={createStore(mainReducer, applyMiddleware(thunk))}>
    <BrowserRouter>
      <Main />
    </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

我的Main.js 组件:

const Main = (props) => {
  return (
    <Switch>
      <Route exact path="/" component={Signin} />
      <Route exact path="/servers" component={Servers} />
    </Switch>
)}

export default withRouter(Main);

我的动作创作者:

export const authorization = (username, password) => (dispatch) =>
  new Promise ((resolve, reject) => {
    fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        username: username,
        password: password,
      })
    }).then( response => {
      if (response.ok) {
          response.json().then( result => {
            console.log("API reached.");
            dispatch(logUserIn(result.token));
            resolve(result);
        })
      } else {
        let error = new Error(response.statusText)
        error.response = response
        dispatch(showError(error.response.statusText), () => {throw error})
        reject(error);
      }
    });
  });

我的 Signin.js 组件:

 handleSubmit(event) {

    event.preventDefault();

    this.setState({ isLoading: true })

    const { username, password } = this.state;
    this.props.onLoginRequest(username, password, this.props.history).then(result => {
      console.log("Success. Token: "+result.token); //I do get "success" in console
      this.props.history.push('/servers') //Changes address, does not render /servers component
    });

  }

const mapActionsToProps = {
  onLoginRequest: authorization
}

最奇怪的是,如果我将 handleSubmit() 方法更改为此 - 一切正常:

The weirdest thing is that if I change my handleSubmit() method to this - everything works perfectly:

  handleSubmit(event) {

    event.preventDefault();

    this.setState({ isLoading: true })

    const { username, password } = this.state;
    this.props.onLoginRequest(username, password, this.props.history).then(result => {
      console.log("Success. Token: "+result.token);
      //this.props.history.push('/servers')
    });
    this.props.history.push('/servers')
  }

如果我尝试从 componentWillReceiveProps(newProps) 方法推送历史记录,也会出现同样的问题 - 它更改地址但不呈现新组件.有人可以解释为什么会发生这种情况以及如何解决吗?

The same issue comes if I try to push history from the componentWillReceiveProps(newProps) method - it changes address but does not render new component. Could someone please explain why this happens and how to fix it?

推荐答案

如果有人感兴趣 - 发生这种情况是因为在推送历史记录之前应用程序正在呈现.当我将历史推送放入我的操作中但就在结果转换为 JSON 之前,它开始工作,因为现在它推送历史,然后才呈现应用程序.

If anyone is interested - this was happening because the app was rendering before the history was pushed. When I put the history push into my action but just before the result is converted into JSON, it started working since now it pushes history and only then renders the App.

export const authorization = (username, password, history) => (dispatch) =>
  new Promise ((resolve, reject) => {
    fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        username: username,
        password: password,
      })
    }).then( response => {
      if (response.ok) {

          //################################
          //This is where I put it

          history.push("/servers");

          //################################

          response.json().then( result => {
            dispatch(logUserIn(result.token));
            resolve(result);
        })
      } else {
        let error = new Error(response.statusText)
        error.response = response
        dispatch(showError(error.response.statusText), () => {throw error})
        reject(error);
      }
    });
  });

这篇关于React history.push() 不渲染新组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆