Состояние не обновляется при использовании обработчика состояния React в setInterval

Вот рабочий пример, который я использовал, чтобы сделать этот запрос моего локального приложения веб-API, запущенного на порту 43305, используя SSL. Я также поставил проект на GitHub. https://github.com/casmer/WebAPI-getauthtoken

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Net.Http;
using System.Web;

namespace GetAccessTokenSample
{
  class Program
  {
    private static string baseUrl = "https://localhost:44305";

    static void Main(string[] args)
    {

      Console.WriteLine("Enter Username: ");
      string username= Console.ReadLine();
      Console.WriteLine("Enter Password: ");
      string password = Console.ReadLine();

      LoginTokenResult accessToken = GetLoginToken(username,password);
      if (accessToken.AccessToken != null)
      {
        Console.WriteLine(accessToken);
      }
      else
      {
        Console.WriteLine("Error Occurred:{0}, {1}", accessToken.Error, accessToken.ErrorDescription);
      }

    }


    private static LoginTokenResult GetLoginToken(string username, string password)
    {

      HttpClient client = new HttpClient();
      client.BaseAddress = new Uri(baseUrl);
      //TokenRequestViewModel tokenRequest = new TokenRequestViewModel() { 
      //password=userInfo.Password, username=userInfo.UserName};
      HttpResponseMessage response =
        client.PostAsync("Token",
          new StringContent(string.Format("grant_type=password&username={0}&password={1}",
            HttpUtility.UrlEncode(username),
            HttpUtility.UrlEncode(password)), Encoding.UTF8,
            "application/x-www-form-urlencoded")).Result;

      string resultJSON = response.Content.ReadAsStringAsync().Result;
      LoginTokenResult result = JsonConvert.DeserializeObject(resultJSON);

      return result;
    }

    public class LoginTokenResult
    {
      public override string ToString()
      {
        return AccessToken;
      }

      [JsonProperty(PropertyName = "access_token")]
      public string AccessToken { get; set; }

      [JsonProperty(PropertyName = "error")]
      public string Error { get; set; }

      [JsonProperty(PropertyName = "error_description")]
      public string ErrorDescription { get; set; }

    }

  }
}

37
задан Yangshun Tay 6 November 2018 в 18:27
поделиться

2 ответа

Это решения не работают на меня, потому что я должен получить переменную и сделать некоторый материал не просто, обновляет его.

я заставляю обходное решение получать обновленное значение рычага с обещанием

, Например:

async function getCurrentHookValue(setHookFunction) {
  return new Promise((resolve) => {
    setHookFunction(prev => {
      resolve(prev)
      return prev;
    })
  })
}

С этим я могу получить значение в функции setInterval как это

let dateFrom = await getCurrentHackValue(setSelectedDateFrom);
0
ответ дан 7 November 2019 в 13:20
поделиться

Если кто-то должен управлять очередью

Скажем, для показа уведомлений с интервалом 3 секунд (метод "первым пришел - первым вышел") со способностью продвинуть новые сообщения когда-либо.

пример Codesandbox.

import React, {useState, useRef, useEffect} from "react";
import ReactDOM from "react-dom";

import "./styles.css";

let x = 1 // for testing
const fadeTime = 3000 // 3 sec 

function App() {
  // our messages array in what we can push at any time
  const [queue, setQueue] = useState([]) 

  // our shiftTimer that will change every 3 sec if array have items
  const [shiftTimer, setShiftTimer] = useState(Date.now())

  // reference to timer
  const shiftTimerRef = useRef(null)

  // here we start timer if it was mot started yet
  useEffect(() => {
    if (shiftTimerRef.current === null && queue.length != 0) {
      startTimer()
    }
  }, [queue])

  // here we will shift first message out of array (as it was already seen)
  useEffect(() => {
    shiftTimerRef.current = null
    popupShift()
  }, [shiftTimer])

  function startTimer() {
    shiftTimerRef.current = setTimeout(() => {
      setShiftTimer(Date.now)
    }, fadeTime )
  }

  function startTimer() {
    shiftTimerRef.current = setTimeout(() => setShiftTimer(Date.now), fadeTime )
  }

  function popupPush(newPopup) {
    let newQueue = JSON.parse(JSON.stringify(queue))
    newQueue.push(newPopup)
    setQueue(newQueue)
  }

  function popupShift() {
    let newQueue = JSON.parse(JSON.stringify(queue))
    newQueue.shift()
    setQueue(newQueue)
  }

  return (
    <div>
      <button onClick={() => popupPush({ message: x++ })}>Push new message</button>
      <div>{JSON.stringify(queue)}</div>
    </div>
  )
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
0
ответ дан 7 November 2019 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: