как получить, получая из axios, данные в useState с помощью функционального компонента реакции

Я работаю над реакционным проектом, созданным jhipster. Когда я выполняю запрос на получение из моего rest api.

GET http://localhost:8080/api/account
Accept: */*
Cache-Control: no-cache
Authorization: Bearer bearerValue

Я получаю такой ответ:

HTTP/1.1 200 OK
Expires: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
X-XSS-Protection: 1; mode=block
Pragma: no-cache
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com data:
Date: Sun, 05 Apr 2020 18:26:07 GMT
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
Feature-Policy: geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'
Transfer-Encoding: chunked
Content-Type: application/json

{
  "id": 3,
  "login": "admin",
  "firstName": "Administrator",
  "lastName": "Administrator",
  "email": "admin@localhost",
  "imageUrl": "",
  "activated": true,
  "langKey": "fr",
  "createdBy": "system",
  "createdDate": null,
  "lastModifiedBy": "system",
  "lastModifiedDate": null,
  "authorities": [
    "ROLE_USER",
    "ROLE_ADMIN"
  ]
}

что означает, что API в порядке. Моя проблема в том, как я могу получить результат от обещания axios в моем состоянии, просто выполняя только один запрос.

Вот как я пытаюсь действовать.

портфолио.tsx


export interface IPortfolioProps extends StateProps,
  DispatchProps,
  RouteComponentProps<{ url: string }> {
}

export interface AccountState {
  id: number,
  login: string,
  firstName: string,
  lastName: string,
  email: string,
  imageUrl: string,
  activated: boolean,
  langKey: string,
  createdBy: string,
  createdDate: string,
  lastModifiedBy: string,
  lastModifiedDate: string,
  authorities: Array<string>
}

export const Portfolio = (props: IPortfolioProps) => {

  const currentAccountState = async (): Promise<AccountState> => {
    return await axios.get<AccountState>(`/api/account`)
      .then((response) => {
        return response.data
      });
  };

  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
  // @ts-ignore
  const isAdmin: boolean = () => {
    let as: AccountState;
    currentAccountState()
      .then(response => {
        as = response;
        // eslint-disable-next-line no-console
        console.log('as : ', as);
        return as.authorities.find(
          authority => authority === AUTHORITIES.ADMIN) !== undefined;
      });
  };

  const [admin, setAdmin] = useState(isAdmin);

  return (
    <div>
      {`admin : ${admin}`}
    </div>);
}

при запуске приложения у меня всегда отображается "admin: undefined" в качестве результата на экране, в то время как мой логин в консоли показывает мне ожидаемую учетную запись нужной учетной записи. Я хочу сохранить как состояние, логический ответ - текущий пользователь - admin, в состоянии администратора.

1 ответ

Решение

Я думаю, это потому, что нет значения по умолчанию для admin, так admin является undefinedкогда страница сначала отображается до того, как вы получите ответ от API. Лучше сначала инициализировать его значением по умолчанию, вызвать API при монтировании, а затем обновить состояние с помощью ответа.

Вы можете попробовать что-то вроде:

const [admin, setAdmin] = useState(null);

useEffect(() => {
    if (!admin) {
        const currentAccountState = async (): Promise<AccountState> => {
            return await axios.get<AccountState>(`/api/account`)
                .then((response) => {
                    return response.data
                });
        };
        currentAccountState()
            .then(response => {
                console.log('as : ', response );
                // probably add better handling here in the case that there is no result in the find, otherwise you mightrun into the same issue if admin is undefined again
                setAdmin(response.authorities.find(authority => authority === AUTHORITIES.ADMIN) !== undefined);
            });
    }
}, [admin])

return (
    <div>
        {`admin : ${admin}`}
    </div>
);
Другие вопросы по тегам