在没有关联的组件上调用forceUpdate()

时间:2018-10-01 18:39:40

标签: react-native redux react-redux

我有一个具有按钮的loginComponent,一旦按下它,它就导航到searchQueryComponent。但是,searchQuery组件显示出一些丢失的数据,但是它只需要重新渲染,因为当我稍微滚动它时,数据就会出现。

我正在使用Redux解决此问题。在loginComponent按钮中,我调度了一个UPDATE_RERENDER_KEY操作,该操作由化简器处理,该化简器切换属性,并且searchPage用mapDStateToProps侦听此属性,所以这不意味着在rerenderKey更改时searchComponent将重新呈现吗?每当rerenderKeyChanges时,如何强制SearchQueryPage重新渲染?

LoginComponent:

import FBLoginButton from './button/view'
import React, { Component } from 'react'
import { View } from 'react-native'
import { Container, Text, Button } from 'native-base'
import VepoHeader from '../../formControls/header/view'
import { styles } from '../../style'
import { updateRerenderKey } from '../../product/add/root/action'
import { withNavigation } from 'react-navigation'
import { connect } from 'react-redux'

const mapDispatchToProps = (dispatch: Dispatch<*>): Object => ({
  updateRerenderKey: (): void => {
    dispatch(updateRerenderKey())
  }
})

class LoginView extends Component {
  constructor(props) {
    super(props)
    this.buttonPress = this.buttonPress.bind(this)
  }

  buttonPress() {
    console.log('called')
    this.props.navigation.navigate('Search')
  }

  render() {
    return (
      <Container style={{ backgroundColor: '#27a562' }}>
        <Container
          style={{
            flex: 1,
            height: '100%',
            flexDirection: 'column',
            justifyContent: 'center',
            alignItems: 'center'
          }}>
          <FBLoginButton />
          <Text
            style={{
              color: '#FFF',
              marginTop: 20,
              marginBottom: 20
            }}>
            OR
          </Text>
          <Button
            block
            style={{
              ...styles.labelHeight,
              borderRadius: 4,
              borderWidth: 0.5,
              borderColor: '#FFF',
              width: 250,
              marginLeft: 'auto',
              marginRight: 'auto',
              backgroundColor: 'transparent'
            }}
            onPress={() => {
              this.buttonPress()
              this.props.updateRerenderKey()
            }}>
            <Text style={{ fontSize: 13.5 }}>Continue without Login</Text>
          </Button>
        </Container>
      </Container>
    )
  }
}

const LoginViewComponent = connect(
  null,
  mapDispatchToProps
)(LoginView)

export default withNavigation(LoginViewComponent)

searchQueryComponent

import { Container } from 'native-base'
import React from 'react'
import { ScrollView, View, StyleSheet } from 'react-native'
import { connect } from 'react-redux'
import {
  updateAlertModalIsOpen,
  updateAlertModalHasYesNo,
  updateAlertModalMessage,
  updateAlertModalTitle
} from '../../../formControls/alertModal/action'
import Drawer from 'react-native-drawer'
import { fetchProducts } from './product/action'
import VepoHeader from '../../../formControls/header/view'
// import { toggleMenu } from '../../searchProducts/action'
import { openPageMenu } from '../../../menu/action'
import { styles as appStyle } from '../../../style'
import {
  selectIsGrocerySelected,
  selectSelectedCategory
} from './categoriesMultiselect/selector'
import { selectIsSearchQueryFormValid } from './selector'
import { selectProductSearchQuery } from './product/selector'
import { setSearchQueryPageAllShowSubcategoriesToFalse } from './categoriesMultiselect/action'
import CategoriesMultiselect from './categoriesMultiselect/view'
import GoButton from './goButton/view'
import LocationAutocomplete from './locationAutocomplete/view'
import KeywordInput from './keywordInput/view'
import DistanceSlider from './distanceFromLocationSlider/view'
import { viewStyle } from './style'
import type { Dispatch } from 'redux'
import type { State } from '../../../../sharedModels/state'
import type { StatelessFunctionalView } from '../../../../sharedModels/statelessFunctionalView'
import type { SearchQueryViewProps } from './models/view'
import type { ProductSearchQuery } from './product/models/view'
import Map from '../results/map/view'

const mapStateToProps = (
  state: State
): Object => ({
  vepo: state,
  isSearchQueryFormDisplayed:
    state.product.search.query.root.isSearchQueryFormDisplayed,
  locationListDisplayed: state.product.search.query.root.locationListDisplayed,
  location: state.product.search.query.locationAutocomplete.place,
  isSearchQueryFormValid: selectIsSearchQueryFormValid(state),
  productSearchQuery: selectProductSearchQuery(state),
  isGrocerySelected: selectIsGrocerySelected(state),
  selectedCategory: selectSelectedCategory(state),
  categories: state.product.search.query.categories,
  rerenderKey: state.product.add.root.rerenderKey
})

const mapDispatchToProps = (dispatch: Dispatch<*>): Object => ({
  fetchProducts: (productSearchQuery: ProductSearchQuery): void => {
    dispatch(fetchProducts(productSearchQuery))
  },
  openPageMenu: (): void => {
    dispatch(openPageMenu())
  },
  setSearchQueryPageAllShowSubcategoriesToFalse: (): void => {
    dispatch(setSearchQueryPageAllShowSubcategoriesToFalse())
  },
  updateAlertModalIsOpen: (isOpen: boolean): void => {
    dispatch(updateAlertModalIsOpen(isOpen))
  },
  updateAlertModalMessage: (message: string): void => {
    dispatch(updateAlertModalMessage(message))
  },
  updateAlertModalHasYesNo: (hasYesNo: boolean): void => {
    dispatch(updateAlertModalHasYesNo(hasYesNo))
  },
  updateAlertModalTitle: (title: string): void => {
    dispatch(updateAlertModalTitle(title))
  }
})

let SearchQueryPageView: StatelessFunctionalView<SearchQueryViewProps> = (
  props: SearchQueryViewProps
): React$Element<any> => {
  return (
    <Container>
      <VepoHeader title={'Search Vegan'} />
      <Container style={appStyle.container}>
        <ScrollView
          keyboardShouldPersistTaps="always"
          style={viewStyle(props.locationListDisplayed).scrollView}>
          <View style={viewStyle().innerContainer}>
            <LocationAutocomplete />
          </View>
          <View style={viewStyle().detailsContainer}>
            <DistanceSlider />
            <View>
              <CategoriesMultiselect />
            </View>
            <KeywordInput />
            <GoButton
              isSearchQueryFormValid={props.isSearchQueryFormValid}
              fetchProducts={props.fetchProducts}
              productSearchQuery={props.productSearchQuery}
              uploadSearchQueryProduct={props.uploadSearchQueryProduct}
              updateAlertModalTitle={props.updateAlertModalTitle}
              updateAlertModalIsOpen={props.updateAlertModalIsOpen}
              updateAlertModalHasYesNo={props.updateAlertModalHasYesNo}
              updateAlertModalMessage={props.updateAlertModalMessage}
              selectedCategory={props.selectedCategory}
            />
          </View>
        </ScrollView>
      </Container>
    </Container>
  )
}

let SearchPage = props => {
  return (
    <Drawer
      open={props.isSearchQueryFormDisplayed}
      content={SearchQueryPageView(props)}>
      <Container style={mapStyles.container}>
        <Map />
      </Container>
    </Drawer>
  )
}

SearchPage = connect(
  mapStateToProps,
  mapDispatchToProps
)(SearchPage)

export default SearchPage

const mapStyles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
    height: '100%',
    width: '100%',
    justifyContent: 'flex-end',
    alignItems: 'center'
  },
  location: {
    position: 'absolute',
    top: 0,
    height: 0,
    left: 0,
    right: 0,
    zIndex: 30
  }
})

1 个答案:

答案 0 :(得分:1)

我认为您不需要滚动即可显示数据,我认为这是一个问题,在我使用FlatList时发生在我身上,您可以通过添加它来解决。

removeClippedSubviews={false}