Как извлекать данные, которые нужно извлекать только один раз

#reactjs #angular #redux #fetch #store

#reactjs #angular #redux #выборка #Магазин

Вопрос:

Я хочу извлекать данные из конечной точки API, но мне не нужно извлекать их снова, когда я снова вернусь к экрану или компоненту.

Например, мне нужна конфигурация, которая определяет макет модального диалога, и я хочу получить ее только тогда, когда мы открываем диалог. И в следующий раз, когда мы открываем диалоговое окно, мне не нужно снова извлекать конфигурацию.

Мне нужны решения как для React / Redux, так и для Angular 6 .

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

1. установите флаг в области видимости модуля — он будет общим для всех экземпляров

Ответ №1:

В react вы могли бы сделать это следующим образом:

Состояние Redux

 {
  MODAL_CONFIG: null   // INITIAL STATE AS null
}
  

YourModal.js

 // INSIDE YOUR MODAL COMPONENT

const dispatch = useDispatch();  // FROM react-redux
const MODAL_CONFIG = useSelector((state) => state.MODAL_CONFIG); // FROM react-redux

useEffect(() => {                            // EFFECT TO FETCH API
  if (MODAL_CONFIG === null) {               // WILL ONLY FETCH API IF MODAL_CONFIG STATE IS null
    fetchApiForConfig().then((data) => 
      dispatch(
        type: "UPDATE_MODAL_CONFIG",
        payload: {config: data}
      );
    );
  }
},[dispatch,MODAL_CONFIG]);

return(
  MODAL_CONFIG ?
    <YourModalUI/>    // IF MODAL_CONFIG EXISTS. DISPLAY MODAL
  : <SomeSpinner/>    // ELSE DISPLAY SPINNER
);
  

reducer.js

 function reducer(state,action) {
  switch(action.type) {
    case "UPDATE_MODAL_CONFIG": {
      return({
        ...state,
        MODAL_CONFIG: action.payload.config
      });
    }
    default: {
      return state;
    }
  }
}
  

Много возможностей для улучшений, но это в основном то, что вам нужно сделать.

Ответ №2:

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

Обслуживание

 @Injectable({ providedIn: 'root' })
export class ConfigClass {
  private configSource = new ReplaySubject<any>(1);    // <-- buffer 1, will emit the last result on subscription
  public config$ = this.configSource.asObservable();

  constructor(private http: HttpClient) {
    this.getConfig();         // <-- call API once
  }

  getConfig() {
    this.http.get('url').subscribe(
      res => this.configSource.next(res),
      err => this.configSource.error(err)
    );
  }
}
  

Компонент

 export class SomeComponent implements OnInit {
  config: any;

  constructor(private configService: ConfigService) { }

  ngOnInit() {
    this.configService.config$.subscribe(
      res => this.config = res,
      err => { }
    );
  }
}
  

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

1. Что происходит, когда SomeComponent уничтожается и воссоздается снова? А служба конфигурации используется где-то еще?

2. Вы могли бы включить { providedIn: 'root' } в @Injectable декоратор сервиса. Это сделает его одноэлементным (только один экземпляр). Если компонент закрыт / уничтожен и снова открыт, он будет получать уведомления от config$ observable. API будет запущен только один раз при создании службы.