isOrganizationCreated
всегда будет содержать начальное значение false
, поскольку переменной в области действия useCreateOrganization
никогда не назначается новое значение, так что это скорее базовая вещь закрытия JavaScript (если вы хотитечтобы узнать больше, посмотрите на * 1 ниже)
Проблема также заключается в том, что вы хотите реализовать императивный опрос (until
) в мире React. Вместо этого вы должны принять декларативную природу React, используя state
и props
для запуска нового цикла рендеринга. Таким образом, вместо опроса вы можете вызвать API mockCreateOrg
, который, в свою очередь, устанавливает новое состояние. Это новое состояние запускает повторное рендеринг, который может привести к побочным эффектам - например, console.log("done")
.
Я не уверен, почему вы хотите использовать Hooks именно в вашем образце, поэтому вот базовый пример выборки стри состояния: когда 1) крючок находится в "idle"
, 2) создается организация ("pending"
), 3) создание орги завершено ("created"
).
Codesandbox
import * as React from "react";
import { render } from "react-dom";
import { useEffect, useState } from "react";
export const useCreateOrganization = (): {
createOrganization: (organizationName: string) => Promise<any>;
} => {
const [state, setState] = useState<"idle" | "pending" | "created">("idle");
useEffect(() => {
let interval;
if (state === "pending") {
interval = setInterval(() => console.log("not done yet!"), 500);
} else if (state === "created") {
console.log("done");
// ...do some other things here...
setState("idle");
}
return () => interval && clearInterval(interval);
}, [state]);
// Fakes org creation on a server.
const mockCreateOrg = (orgName: string) => {
setTimeout(() => {
setState("created");
}, 1500);
};
const createOrganization = async (organizationName: string): Promise<any> => {
mockCreateOrg(organizationName);
setState("pending");
};
return { createOrganization };
};
function App() {
const { createOrganization } = useCreateOrganization();
const handleCreateOrg = () => {
createOrganization("New Org Name");
};
return (
<div className="App">
<button onClick={handleCreateOrg}>Start process</button>
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
Дополнительная информация: замыкания в React Hooks (* 1)
При вызове замыкания createOrganization
будет использоваться переменная isOrganizationCreated
, определенная ввнешняя область (useCreateOrganization
тело функции), которая во время вызова имеет значение начального состояния false
. isOrganizationCreated
всегда будет иметь буквальное значение false
в этой области, переназначение никогда не произойдет (с const
также невозможно). Запустив изменение состояния с помощью setIsOrganizationCreated
, React внутренне обновляет свою ячейку памяти компонента , и с новым циклом рендеринга снова вызывает useCreateOrganization
- теперь с обновленным состоянием isOrganizationCreated
. Хотя это не меняет область закрытия первого useCreateOrganization
вызова.
Надеюсь, это поможет.