#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.