Совместное использование данных (массива) между двумя экранами в режиме вкладок с использованием react-навигации в react native

#reactjs #react-native #react-navigation #react-state

#reactjs #react-native #react-навигация #react-состояние

Вопрос:

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

 state = { locations: [] };

componentDidMount() {
  this.getAllLocations();
}

  async getAllLocations() {
    let locations = await this.getMoviesFromApi();
    this.setState({ locations });
  }
  

я просто хочу, чтобы этот массив находился в одном месте, и оба компонента должны совместно использовать этот единый источник истины. таким образом, изменения, внесенные одним экраном, отражаются на другом экране. Возможно ли это без redux?

Ответ №1:

RN 0.59 с его выпуском открыла большие возможности. Одним из них являются перехватчики react, который доступен в последней версии… в будущем перехватчики react будут использоваться повсеместно. Поверьте мне. Итак, некоторое время назад я искал возможности создания глобального состояния с помощью react hooks и нашел библиотеку reactn. В нем используются перехватчики react native, и даже вы можете использовать глобальное состояние в компонентах КЛАССА. что открывает новые возможности для тематизации и совместного использования данных. Теперь мое приложение поддерживает светлый / темный режим, динамический размер шрифта, языки и раннюю реализацию «порталов» с использованием только этой библиотеки.

Самое приятное в этом то, что вы можете использовать его как state. Нет необходимости в provider или redux (хотя он предоставляет это). Он может быть интегрирован с react navigation (для этого требуется изменить некоторый исходный код, максимум, добавить «n» в react и ссылаться на глобальную переменную). Это потрясающе, и мне это нравится.

Я думал написать статью об этом на medium, потому что библиотека не так популярна в сообществе RN, но надеюсь, что вы дадите ей шанс, библиотека всего 22 КБ, что меньше, чем на один полноценный компонент.

В качестве альтернативы вы могли бы подумать о написании собственной библиотеки с использованием перехватов. Но это будет сложно. Попробуйте, пути назад нет

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

1. Как автор, я был бы чрезвычайно признателен за статью Medium. Я ценю здесь добрые слова.

Ответ №2:

Это возможно, если у вас одноэлементный объект :

 export default class SharedData {
  constructor(){
  if(SharedData.instance){
     return SharedData.instance;
   }

   this.state = {locations:[]};
   this.listners =[];
   SharedData.instance = this;
   return SharedData.instance;
 }

 setLocations(locations){
    this.state.locations = locations;
    this.listners.forEach(listner=>listner(this.state.locations));
 }
 getLocations(){
     return this.state.locations;
 }
 addListner(listner){
    this.listners.push(listner);
     return listner;
 }
 removeListner(listner){
   let index = this.listners.indexOf(listner);
   if(index > -1){
      this.listners.splice(index,1);
    }
 }
} 
  

и затем на каждой вкладке, где вы хотите получить доступ к общим местоположениям, укажите:

 // get an instance of SharedData
this.sharedData = new SharedData();
// subscribe to locations changes
this.listner = sharedData.addListner((locations)=>{
   this.setState({locations});
});

 // set locations
 this.sharedData.setLocations([]);

  // unregister when destroying the component
  this.sharedData.removeListner(this.listner);
  

Ответ №3:

Я предполагаю, что для достижения вашей цели вам понадобится какой-то механизм для хранения «глобальных данных», и если вам не нравится Redux, потому что для решения этой простой задачи совместного использования глобальных данных требуется много настроек, тогда вы должны указать … который очень прост в настройке

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

1. да, это тоже может работать, но я не хочу, чтобы мой код зависел от внешней библиотеки. поэтому я избежал redux . я просто хочу решить эту проблему, используя подход, основанный только на react.