3

ログイン フォームの再レンダリングとメモリ リークに問題があります。目標は、コンテキストの JWT が有効かどうかをチェックし、有効な場合はリダイレクトするコンポーネントを用意することです。ただし、ログインしてコンテキストを更新すると、とにかくリダイレ​​クトする必要があるときに、コンテキストによって再レンダリングが発生します。これに対する解決策は何ですか?

編集:問題は、認証で2回再レンダリングしているようです.1回はログインで、もう1回はSecuredRouteです。よりエレガントなソリューションはありますか?

useValidateToken.js

export default token => {
  const [validateLoading, setLoading] = useState(true);
  const [authenticated, setAuthenticated] = useState(false);

  useEffect(() => {
    fetch(`/validate_token`, {
      method: "GET",
      headers: { Authorization: "Bearer " + token }
    })
      .then(resp => {
        if (resp.ok) setAuthenticated(true);

        setLoading(false);
      })
      .catch(_ => setLoading(false));
  }, [token]);

  return { validateLoading, authenticated };
};

ログイン.js

function Login(props) {
  const {token, setToken} = useContext(TokenContext)

  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const { isLoading: validateLoading, authenticated } = useValidateToken(token);
  const [shouldRedirect, setShouldRedirect] = useState(false);

  const [isLoading, setIsLoading] = useState(false);
  const [isInvalid, setIsInvalid] = useState(false);

  function login() {
    setIsLoading(true);

    fetch(`/login`, { ... })
      .then(resp => resp.json())
      .then(body => {
        if (body.jwt) {
          setToken(body.jwt);
          setShouldRedirect(true);
        } else {
          setIsInvalid(true);
          setTimeout(function () { setIsInvalid(false) }, 3000)
          setIsLoading(false);
        }
      })
      .catch(_ => setIsLoading(false));
  }

  return validateLoading ? (
    // Skipped code
  ) : shouldRedirect === true || authenticated === true ? (
    <Redirect to={props.location.state ? props.location.state.from.pathname : "/"} />
  ) : (
    <div className="login">
      // Skipped code
        <LoginButton loading={isLoading} login={login} error={isInvalid} />
      </div>
    </div>
  );
}

ルートは、カスタム コンポーネントを使用して保護されます。これは、ルートを保護し、無効なトークンがある場合にログインにリダイレクトするために行われます。

App.js

// Skipped code
const [token, setToken] = useState(null);
const { authenticated } = useValidateToken(token)

//Skipped code
<SecuredRoute exact path="/add-issue/" component={AddIssue} authenticated={authenticated} />

function SecuredRoute({ component: Component, authenticated, ...rest }) {
  return (
    <Route
      {...rest}
      render={props =>
        authenticated === true ? (
          <Component {...props} {...rest} />
        ) : (
          <Redirect to={{ pathname: "/login", state: { from: props.location } }} />
        )
      }
    />
  );
}
4

0 に答える 0