2015-02-13 2 views
1

Я использую React с реактивным маршрутизатором и Reflux в качестве моего хранилища данных, но я не уверен, как лучше всего справляться с постоянством, чтобы разрешить обновление страницы.React routing and persistence на странице refresh

Мои компоненты подключаются к хранилищу с помощью Reflux.connect, но поскольку хранилище извлекает данные из бэкэнд, оно еще не доступно, когда компоненты сначала инициализируются и визуализируются.

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

Я решил это, постоянно сохраняя копию данных в LocalStorage и обслуживая это из хранилища Reflux getInitialState(), чтобы все компоненты получали данные перед их рендерингом.

Интересно, правильно ли это сделать. Когда по какой-то причине локальные данные хранилища очищаются или повреждаются, интерфейс становится пустым, поскольку компоненты не могут получить доступ к правильным данным. Подструктур и свойств не существует и вызывают ошибки JavaScript. Это похоже на беспорядочное и ненадежное решение.

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

------ редактировать ----- Чтобы ответить на комментарий WiredPrairie:

1) Почему вы инициализацией компоненты с данными в getInitialState?

Когда мои компоненты используют Reflux.connect, у них нет данных в их состоянии еще в первом рендере, так как хранилище все еще нужно извлекать его данные. В настоящее время мои представления не работают с неопределенными данными. Вернув локально хранимый кеш из хранилища Reflux в getInitialState(), все подключенные компоненты получат эти данные до их первого вызова рендеринга.

2) Что вызывает обновление страницы и почему нельзя загружать данные таким же образом, как это было в первый раз?

Это в основном обходной путь, который я должен был создать вокруг livereload, обновляющего страницу, когда я делаю изменения (позже рассмотрю использование реактивного hotloader, но пока не является параметром), но пользователи могут также просто обновить обновление, когда они находятся где-то в мои вложенные взгляды, и это будет иметь тот же эффект. Когда они обновляются вручную, они не входят в приложение в начале.

3) Когда компоненты подключены к событиям изменений в магазине, почему они не обновляются?

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

Из ответов до сих пор у меня возникает ощущение, что то, что я делаю с localStorage, является обычным способом сделать это. Кэш-файл локально в localStorage или sessionStorage или что-то подобное, и обслуживать эти данные сразу после обновления.

Я должен сделать свои взгляды более надежными, грациозно передавая пустые данные в нечетном случае, что localStorage не работает должным образом.

+0

Это чувствует немного широкий для переполнения стека (может быть, как это, кажется, требуется немного вперед и назад, чтобы получить разумное решение). – WiredPrairie

+1

Некоторые вопросы о вашей реализации (что может быть полезно, если вы отредактировали вопрос, чтобы включить более подробную информацию) ... 1) Почему вы инициализируете компоненты данными в 'getInitialState'? 2) Что вызывает обновление страницы и почему нельзя загружать данные так же, как это было в первый раз? 3) Когда компоненты подключены к событиям изменения магазина, почему они не обновляются? – WiredPrairie

+0

Я добавил дополнительную информацию –

ответ

0

Я кэшировал каждый магазин в sessionStorage, когда его emitChange() запускает и инициализирует хранилище из sessionStorage, если хранятся кешированные данные, или нулевые значения в противном случае.Это похоже на работу, при условии, что представления могут обрабатывать нулевые значения, что, вероятно, является хорошей идеей в любом случае (похоже, что это ваша основная проблема).

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

Я не пробовал рефлюкс, но в обычном Flux это будет выглядеть следующим образом (возможно, вы можете применить тот же принцип):

var _data; 

if (sessionStorage.PostStore) 
    _data = JSON.parse(sessionStorage.PostStore); 
else { 
    _data = { 
    posts: null 
    }; 
    BackendAPI.getPosts(function(err, posts) { 
    if (posts) { 
     PostActions.setPosts(posts); 
    } 
    }); 
} 

... 

AppDispatcher.register(function(payload) { 
    var action = payload.action; 

    switch (action.actionType) { 

    ... 

    case Constants.SET_POSTS: 
     _data.posts= action.data.posts; 
     break; 

    default: 
     return true 
    } 

    // Update cache because state changed 
    sessionStorage.PostStore = JSON.stringify(_data); 

    PostStore.emitChange(); 
    return true; 
}); 
+0

Спасибо, я согласен с этим в качестве ответа, потому что нет другого шаблона. Я уже это делал. Тогда мне придется делать больше проверок нулевых данных в моих представлениях. –