2016-09-23 2 views
0

Что я пытаюсь достичь, так это: я хочу проверить, открыт ли NavigationDrawer, и если да, то когда пользователь нажимает (на Android), я хочу закрыть ящик вместо отказа от приложения. У меня есть булевое (isDrawerOpen) в сохраненном Redux, которое обновляется должным образом.React Native: Call Redux getState() внутри Компонент

Моя проблема в том, что я не могу понять, как позвонить getState() внутри моего компонента. Компонент выглядит примерно так:

class MainScreen extends Component { 
    constructor(props) { 
    super(props) 

    BackAndroid.addEventListener('hardwareBackPress', function() { 
     if (somehow.getState().isDrawerOpen) { 
     // Close drawer. 
     return true; 
     } 

     return false; 
    }); 
    } 

    render() { 
     return ... 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
    ... 
    } 
} 

export default connect(mapStateToProps)(MainScreen) 

И магазин создан в другой контейнер компонента, например:

export default class App extends Component { 
    render() { 
     return (
      <Provider store={store}> 
       <MainScreen /> 
      </Provider> 
     ); 
    } 
} 

В моем MainScreen компоненте всякий раз, когда мне нужно направить действие, я его вызывающий this.props.dispatch(someAction()). Однако this.props.getState(), похоже, не существует.

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

Заранее благодарен!

+0

Вы получаете «состояние» redux, используя mapStateToProps и используя реквизит внутри вашего компонента. В большинстве случаев с сокращением вы не будете использовать 'this.state' внутри своих компонентов, вместо этого вы будете использовать' this.props', который изначально поступает с вашего mapStateToProps. В вашем случае я бы сохранил состояние открытия/закрытия выдвижных ящиков в самом состоянии редукции, затем у вас есть действие redux, чтобы открыть/закрыть его (изменить bool или что-то еще). Затем вы можете сопоставить его в свой компонент, что-то вроде 'this.props. isDrawerOpen'. – ajmajmajma

+0

Спасибо за ваш ответ. Да, я сохраняю состояние ящика в Redux, и у меня есть конкретные действия для этого. Кроме того, всякий раз, когда изменяется состояние ящика, mapStateToProps запускается с правильной информацией. Все идет нормально. Проблема в том, что MainScreen не может обновить свои собственные реквизиты, поэтому мне нужно будет отобразить состояние, которое я получил от Redux, в состояние MainScreen, вызвав 'setState'. Однако это снова вызовет «render()» MainScreen, и это не то, что я хочу. – George

+0

Вам следует избегать использования setState, если можно, я бы просто использовал действие redux или какое-либо состояние инициализации? Есть трюк, когда вы избегаете рендеринга, проверяя реквизит 'mustComponentUpdate'. Например, реакция mixin PureRenderMixin делает именно это, чтобы попытаться избежать рендеринга, если реквизит не изменился. – ajmajmajma

ответ

1

Нельзя помещать BackAndroid.addEventListener внутри конструктора, потому что реквизиты там не меняются. Вам необходимо поставить слушателя в componentDidMount или componentWillMount, чтобы быть в состоянии проверить последнее состояние вашего props. Затем в вашем слушателе проверьте наличие this.props.isDrawerOpen, который должен автоматически передаваться и обновляться сверху с connectmapStateToProps. Вам не нужно звонить getState внутри компонента connect ed.

+0

Привет и спасибо за ответ. Не могли бы вы помочь мне понять немного больше, что вы имеете в виду? Я не вижу, как «MainScreen» может обновить свои собственные реквизиты. Сначала вызывается «mapStateToProps», и я могу отобразить состояние Redux в некоторых новых реквизитах. Затем «componentWillReceiveProps (nextProps)» внутри MainScreen будет запускаться с этими новыми реквизитами. Наконец, поскольку MainScreen не может обновить свои собственные реквизиты, вместо этого мне придется сопоставить эти реквизиты в состоянии MainScreen, вызвав 'setState'. Но это снова вызовет render(), и я не хочу, чтобы это произошло. Или я чего-то не хватает? – George

+0

Можете ли вы показать мне, как вы подключили свой ящик к сокращению? – rclai

+0

Я использую реактивный ящик, и я помещаю его в другой компонент, отличный от MainScreen. MainScreen на самом деле является ребенком ящика. В ящике onOpen/onClose я вызываю 'this.props.dispatch (updateDrawerState (true)), передавая true/false соответственно. «MapStateToProps», подключенный к MainScreen, всегда имеет правильное состояние Redux. Так что работает так, как ожидалось. – George