Строковое значение useState становится пустым после сохранения значения в ответе API на него

#reactjs #typescript

#reactjs #typescript

Вопрос:

То, что я пытаюсь здесь сделать, это извлечь идентификатор (номер) из ответа API, разобрать его в строку и установить для него переменную состояния. Однако, когда я регистрирую его в консоли, он выдает мне пустую строку, которая является значением по умолчанию. Если кто-нибудь может дать мне предложение или сказать мне, что не так, это было бы очень признательно. Мой кратко воспроизведенный фрагмент кода приведен ниже:

   const [userId, setUserId] = useState<string>("");


  const getMyUserId = async () => {
    const { data: objects } = await axios.get("/"); 
    const user_id = objects.objects[0].id.toString(); 
    setUserId(user_id);
    console.log("userId", userId); <- output is empty string
  };

  const getMyCalendarId = async () => {
    const url = `/${userId}/cal/calendars`;
    const { data: objects } = await axios.get(`${url}`);
    const calendar_id = objects.objects[0].id.toString();
    setCalendarId(calendar_id);
  };
    
  useEffect(() => {
    getMyUserId(); <- render every time page is loaded
    getMyCalendarId
  }, []);
 

Комментарии:

1. setUserID — это асинхронный процесс. console.log("userId", userId) запускается до setUserId(user_id) завершения. Вам нужно дождаться завершения перед console.log(«userId», userId)

2. Вы правы. Однако, userId будет использоваться для другой функции, которая вызывает другой вызов api, используя его, например, await axios.get( /api/${userId} /abc . Затем URL-адрес запроса api становится ike /api/abc (в идеале я хочу, чтобы это было /api/12345(userId)/abc ). Есть ли какой-либо способ, которым я могу вызвать последнюю функцию после того, как убедился userId , что она была успешно установлена?

3. useEffect(()=>{ getMyUserId(); }, []) ; —> Идентификатор пользователя будет изменен после загрузки страницы, и useEffect(()=>{getMyCalendarId(); }, [userId]); —> После изменения идентификатора пользователя будет вызван getMyCalendarId(). Компонент может иметь несколько useEffect();

Ответ №1:

Чтобы получить идентификатор пользователя, к которому вы должны получить доступ data , вместо objects . Вот так:

 const user_id = data.objects[0].id.toString(); 
 

objects это типизация data , это не фактическое свойство.

Комментарии:

1. TS говорит data , что не может быть найден. Я даже пытался const data = await axios.get('/) , но все равно userId пусто. Как упоминалось выше @ioedeveloper, для другой функции, которая использует userId gets, вызывается раньше user_id , установлено значение userId .

2. Если вы console.log(data) , каков ваш результат? Вы действительно получаете что-то обратно с сервера? Кроме того, если вы хотите использовать userId inside of, вы должны await getMyUserId() использовать внутри useEffect , потому что теперь он будет вызывать getMyCalendarId() до получения идентификатора пользователя.