2016-10-13 4 views
5

Я новичок в React Native. Я использую redux архитектуры для моего реагировать родной app однако я столкнулся с проблемой из-за global store state of redux.React Native - Redux: несколько экземпляров того же состояния в приложении

Предположим, например, Вперед в приложении Я прохожу, как показано ниже. enter image description here

Некоторое время назад навигации,

enter image description here

Согласно Redux архитектуры, Он изменяет состояние каждого экземпляра страницы, присутствующую в стеке навигации с последним государством в магазин.

Вот код для приведенного выше примера,

Page.js [Component]

class Page extends Component{ 

    componentWillMount(){ 

    } 

    render(){ 
     var {image,apiCall} = this.props; 

     return (
     <View> 
      <Image Source={{uri:image}} style={{// style for the image}}> 
     </View> 
    )} 

    componentDidMount(){ 
     this.props.apiCall(this.props.route.data.link); // this.props.route.data.link -> this is just a link for             // the apiCall 
    } 

    componentWillReceiveProps(){ 

    } 

    shouldComponentUpdate(nextProps, nextState){ 
     if(this.props.image==nextProps.image){ 
      return false; 
     } 
     return true; 
    } 

    componentWillUpdate(){ 

    } 

    componentDidUpdate(){ 

    } 

    componentWillUnmount(){ 

    } 
} 

    const mapStateToProps = (state) => { 
    return { 
    image: state.PageDataReducer.image 
    }; 
    }; 

    const mapDispatchToProps = (dispatch) => { 
    return { 
     apiCall: (link) => { 
     dispatch(fetchProduct(link)); // fetchProduct() -> is a function which fetches the product from the         // network and dispatches the action. 
     }, 
    }; 
    }; 

export default connect(mapStateToProps,mapDispatchToProps)(Page); 

fetchProduct() [Функция для извлечения продукта]

export function fetchProduct(link) { 
    return function(dispatch){ 
    // fetches the product over network 
    dispatch(fetchedProduct(productLink)); 
    } 
} 

Продукт [Действие]

export const fetchedProduct = (productLink) => { 
    return { 
    type: FETCHED_PRODUCT, 
    image: image 
    }; 
}; 

PageDataReducer [Редуктор]

export default function PageDataReducer(state = initialState, action) { 

    switch (action.type) { 

    case FETCHED_PRODUCT: 
    var newState = { 
     ...state, 
     image: action.image 
    }; 
     return newState; 

    default: 
     return state; 
    } 
} 

Мои наблюдения: Когда же страница происходит в навигации и состояние в магазине этой страницы получает изменить то вызывает mapStateToProps() этой страницы количество раз, что страница находится в стеке навигации. И, следовательно, это количество раз, когда оно перебирает методы жизненного цикла этой страницы, чтобы изменить состояние в соответствии с последним состоянием.
В этом примере, когда я нажмите на банан в ящике, он изменяет состояние из манго банан в магазине и mapStateToProps() вызывается в 3 раза (потому что страница присутствует в 3 раза в стеке навигации) и, следовательно, все методы жизненного цикла реакции от компонентаWillReceiveProps() на componentDidUpdate() вызывается 3 раза только для изменения состояния этой страницы в соответствии с последним состоянием.

Что я хочу?: Я хочу разное состояние страницы в навигации, так что, возвращаясь, я вижу все разные продукты, которые я посетил.

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

+0

Вы можете уточнить свой вопрос? –

+0

@DamienLeroux, да, я отредактировал мой вопрос выше. можете ли вы, пожалуйста, пройти через это снова. –

+0

Вы сказали: «Согласно архитектуре redux, он изменяет состояние каждого экземпляра страницы, присутствующей в стеке навигации, с самым последним состоянием в магазине». Архитектура redux не делает этого без кода, чтобы сохранить каждое состояние приложения где-то. Может быть, это ваша проблема здесь –

ответ

-1

То, что вы пытаетесь сделать, не может быть сделано только с помощью Redux.

Необходимо историзировать в браузере или приложении, чтобы ваши изменения изменились в качестве навигации. HistoryJS используется для этого. Этот модуль используется react-router и предлагает хороший UX в веб-навигации.

Таким образом, либо используйте react-router, чтобы объявить разные страницы (по одному для каждого фрукта) или, по крайней мере, использовать HistoryJS, чтобы сохранить состояние навигации программно.

Я не знаю, как реагирует маршрутизатор на собственные приложения, поэтому взгляните на React Native Router. Он представляет способ handle navigation with Redux on native app.

+0

Да, на самом деле я попытался использовать библиотеку [** react-native-router-flux **] (https://github.com/aksonov/react-native-router-flux) и даже с реагировать на нативный ** навигационный экспериментальный компонент **. Но не получилось. Проблема связана с архитектурой redux. Если я делаю это с нормальным состоянием (а не с сокращением), конечно, он работает правильно. Но хорошо ли использовать состояние для некоторых компонентов и сокращений для некоторых? и если да, то может ли состояние разных компонентов быть управляемым во всем приложении? –

+0

Нет правил относительно строгого использования. В зависимости от того, что вы хотите сделать, вы можете использовать как состояния редукции, так и компоненты. состояние компонента не должно управляться во всем приложении. –

1

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

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

В функции mapStateToProps сначала извлекается текущий выбор, это должен быть идентификатор. Вы также можете извлечь его из другого места, например. из компонентов реквизита (второй аргумент mapStateToProps). Затем вы используете этот извлеченный идентификатор, чтобы получить уже загруженные данные из хранилища данных домена. Если выбранные данные не находятся в хранилище (например, когда пользователь впервые посещает страницу или уже собрал мусор), вы помещаете пустое значение в реквизиты, и это будет означать, что крючки componentDidMount или componentWillReceiveProps что они должны выполнить запрос на загрузку данных (это может быть реализовано как отправка действия, которое сигнализирует о потребности в данных для саги или thunk, в зависимости от того, что вы используете для управления загрузкой данных), в то время как это происходит, рендер верните некоторую «загрузку ...» заглушки. Когда запрос завершится, другая отправка обновит обновление хранилища данных домена, которое приведет к подключению, чтобы вызвать другой вызов mapStateToProps, и это приведет к обнаружению того, что выбранные данные уже находятся в хранилище, поэтому новый запрос на загрузку данных не будет сделан , и рендер будет иметь достаточно данных для отображения.

Смежные вопросы