this.setState не работает должным образом - PullRequest
1 голос
/ 09 марта 2019

Я не знаю, почему, но после того, как я вошел в систему, а затем вышел из системы, я не могу переключаться между панелью регистрации и входа в «AuthForm.jsx», «this.setState» не будет работать.Я объяснил, как код разбивается на кусочки, чтобы увидеть, где он может пойти не так.

Журналы консоли перед входом в систему:

authToggleDisplaySignUp pressed"
authToggleDisplaySignUp true {displaySignUp: false}
authToggleDisplaySignUp pressed"
authToggleDisplaySignUp true {displaySignUp: true}
authToggleDisplaySignUp pressed"
authToggleDisplaySignUp true {displaySignUp: false}
authToggleDisplaySignUp pressed"
authToggleDisplaySignUp true {displaySignUp: true}

Журналы консоли после входа в систему:

authToggleDisplaySignUp pressed
authToggleDisplaySignUp true {displaySignUp: true}
authToggleDisplaySignUp pressed
authToggleDisplaySignUp true {displaySignUp: true}
authToggleDisplaySignUp pressed
authToggleDisplaySignUp true {displaySignUp: true}

Это "Root.jsx"

import React, { Component } from "react";
import { connect } from "react-redux";
import Home from "./Home.jsx";
import AuthForm from "./AuthForm/AuthForm.jsx";
import { fetchAuthenticated } from "../actions/account.js";     

class Root extends Component {
  state = {
    displaySignUp: false
  };

  authToggleDisplaySignUp = () => {
    console.log("authToggleDisplaySignUp pressed");
    this.setState(
      {
        displaySignUp: !this.state.displaySignUp
      },
      () => {
        console.log("authToggleDisplaySignUp true", this.state);
      }
     );
  };

  render() {
    if (this.props.account.loggedIn && !this.state.displaySignUp) {
      return <Home authToggleDisplaySignUp={this.authToggleDisplaySignUp} />;
    } else {
      return (
        <AuthForm
          displaySignUp={this.state.displaySignUp}
          authToggleDisplaySignUp={this.authToggleDisplaySignUp}
        />
      );
    }
  }
}
export default connect(
  ({ account }) => ({ account }),
  { fetchAuthenticated }
)(Root);

Это AuthForm.jsx

import React, { Component, lazy, Suspense } from "react";
import Login from "./Login.jsx";
import Loading from "../Loading.jsx";
import Misc from "../Misc.jsx";
import "../css/AuthForm.css";

const SignUp = lazy(() => import("./SignUp.jsx"));

class AuthForm extends Component {
  validateEmail = email => {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(String(email).toLowerCase());
  };

  get loginSignup() {
    if (!this.props.displaySignUp) {
      return (
        <Login
          validateEmail={this.validateEmail}
          toggleDisplaySignUp={this.props.authToggleDisplaySignUp}
        />
      );
    } else {
      return (
        <Suspense fallback={<Loading />}>
          <SignUp
            validateEmail={this.validateEmail}
            toggleDisplaySignUp={this.props.authToggleDisplaySignUp}
          />
        </Suspense>
      );
    }
  }

  render() {
    return (
      <React.Fragment>
        {this.displaySignUpState}
        <div className="holder">
          <div className="leftSide" />
          <div className="rightSide">
            {this.loginSignup}
            <Misc />
          </div>
        </div>
      </React.Fragment>
    );
  }
}

export default AuthForm;

Home.jsx

import React, { Component, lazy, Suspense } from "react";
import Loading from "./Loading.jsx";
import { connect } from "react-redux";
import { fetchInfo } from "../actions/accountInfo.js";
import history from "../history.js";

// Lazy Loading Components
const AccountInfo = lazy(AccountInfo => import("./AccountInfo.jsx"));
const NavBar = lazy(NavBar => import("./NavBar.jsx"));
const Upload = lazy(Upload => import("./Upload.jsx"));

class Home extends Component {
  componentDidMount() {
    this.props.fetchInfo();
    this.checkStatus();
  }

  checkStatus = () => {
    if (!this.props.account.loggedIn) {
      history.push("/");
    }
  };

  render() {
    return (
      <div>
        <Suspense fallback={<Loading />}>
          <NavBar />
        </Suspense>
        <p>Home Page</p>
        <Suspense fallback={<Loading />}>
          <AccountInfo accountInfo={this.props.accountInfo} />
        </Suspense>
        <br />
        <hr />
        <Suspense fallback={<Loading />}>
          <Upload />
        </Suspense>
        <hr />
      </div>
    );
  }
}

export default connect(
  ({ accountInfo, account }) => ({ accountInfo, account }),
  { fetchInfo }
)(Home);

Я использовал "реквизитытуннелирование "для отправки toggleDisplaySignUp компонентам входа в систему и регистрации, они находятся всего на 2 уровня, на самом деле я не использовал toggleDisplaySignUp в" Home.jsx ". Я просто отправил его туда для тестирования чего-то, что нет работатьЯ удалил его.

Login.jsx

<h4 onClick={this.props.toggleDisplaySignUp}>
   <a href="#">Sign Up</a>
</h4>

SignUp.jsx

<h4 onClick={this.props.toggleDisplaySignUp}>
   <a href="#">Login</a>
</h4>

Просто добавьте сюда функцию выхода из системы, которая просто выполняет GET-запрос ксервер и изменяет this.props.account.loggedIn на false

class Logout extends Component {
  reRoute = () => {
    this.props.logout();
  };

  render() {
    return (

      <button onClick={this.reRoute}>Log Out</button>
    );
  }
}

Ответы [ 2 ]

1 голос
/ 09 марта 2019

Я не знаю точно, что я сделал, но код работает сейчас. Я удалил fetchAuthenticated из Root.jsx и BOOM magic. Я буду проверять свои изменения в Git и предоставлю более подробную информацию в качестве комментария к этому ответу. Спасибо всем.

1 голос
/ 09 марта 2019

Имейте в виду, что setState() является асинхронным. Если необходимо выполнять обновления только после обновления состояния компонентов, используйте второй параметр setState().

setState(
  { name: "Michael" },
  () => console.log(this.state)
);

Пожалуйста, проверьте:

...