Не удается получить состояние после входа в систему с помощью Fluxor и Blazor.

avatar
Ces1919
8 августа 2021 в 20:18
118
1
0

Я хочу внедрить управление состоянием в сборку приложения Blazor, поэтому я добавил Fluxor в качестве библиотеки.

Я создал абстрактное корневое состояние, которое содержит общие свойства:

public abstract class RootState
{
    public RootState(bool isLoading, string currentErrorMessage)
        => (IsLoading, CurrentErrorMessage) = (isLoading, currentErrorMessage);

    public bool IsLoading { get; }
    public string CurrentErrorMessage { get; }

    public bool HasCurrentErrors => !string.IsNullOrWhiteSpace(CurrentErrorMessage);

}

Затем я создал состояние входа в систему, которое наследуется от Rootstate:

 public class LoginState : RootState
{
    public bool IsAuthenticated { get; set; }
    public LoginResponseDto UserData { get; set; }
    public LoginState(bool isLoading, string currentErrorMessage, bool isAuthenticated, LoginResponseDto userData)
        :base(isLoading, currentErrorMessage)
    {
        IsAuthenticated = isAuthenticated;
        UserData = userData;
    }
}

После этого я создал класс объектов:

public class LoginFeature : Feature<LoginState>
{
    public override string GetName() => nameof(LoginState);

    protected override LoginState GetInitialState()
        => new LoginState(false, null, false, null);
}

Затем действия:

public class LoginAction
{
    public LoginDto LoginDto { get; }
    public LoginAction(LoginDto LoginDto)
    {
        this.LoginDto = LoginDto;
    }
}

public class LoginAccessFailure : FailureAction
{
    public LoginAccessFailure(string errorMessage)
        :base(errorMessage)
    {

    }
}

public abstract class FailureAction
{
    public string ErrorMessage { get; }

    protected FailureAction(string errorMessage) => ErrorMessage = errorMessage;
}

После этого я создал редьюсер и эффект:

public class LoginReducer
{
    [ReducerMethod]
    public static LoginState ReduceLoginAction(LoginState state, LoginAction action)
        => new LoginState(true, null, false, state.UserData);

    [ReducerMethod]
    public static LoginState ReduceLoginSuccessAction(LoginState state, LoginActionSuccess action)
    {
        Console.WriteLine("State from Reducer", action);
        var result = new LoginState(false, null, action.IsAuthenticated, action.UserData);
        Console.WriteLine("Result from Reducer", result);

        return result;
    }

    [ReducerMethod]
    public static LoginState ReduceLoginFailureAction(LoginState state, LoginAccessFailure action)
        => new LoginState(false, action.ErrorMessage, false, null);
}

Эффект:

 public class LoginEffect : Effect<LoginAction>
{
    private readonly IAccountService _accountService;

    public LoginEffect(IAccountService accountService)
    {
        _accountService = accountService;
    }

    public  override  async Task HandleAsync(LoginAction action, IDispatcher dispatcher)
    {
        try
        {
            var loginResponse = await _accountService.Login(action.LoginDto);

            await Task.Delay(TimeSpan.FromMilliseconds(1000));
            dispatcher.Dispatch(new LoginActionSuccess(loginResponse, true));
        }
        catch (Exception e)
        {
            dispatcher.Dispatch(new LoginAccessFailure(e.Message));
        }
    }
}

Когда я хочу вызвать диспетчера с помощью этой инструкции dispatcher.Dispatch(new LoginAction(new LoginDto { Email = "test@email.com", Password = "test" }));, у меня есть результат в DevTools, но нет данных в IState<LoginState>, поэтому я не могу получить доступ к состоянию. Пожалуйста, в моем коде есть ошибка?

Источник
Anton Eriksson
17 сентября 2021 в 13:47
0

Ваш компонент blazor наследуется от FluxorComponent? В противном случае он не будет автоматически вызывать StateHasChanged().

Ответы (1)

avatar
Peter Morris
10 апреля 2022 в 21:44
0

Что нужно проверить

  1. У вас есть [Inject] перед вашим private IMyState<T> MyState { get; set; }
  2. У вас есть компонент <StoreInitializer/> в основном компоненте приложения.
  3. Ваш компонент происходит от FluxorComponent или вы вручную подписываетесь на MyState.StateChanged и вызываете InvokeAsync(StateHasChanged)