代码之家  ›  专栏  ›  技术社区  ›  BeniaminoBaggins

对没有关系的组件调用forceUpdate()

  •  2
  • BeniaminoBaggins  · 技术社区  · 7 年前

    我有一个loginComponent,它有一个按钮,一旦你按下它,它就会导航到searchquery组件。然而,searchQuery组件显示了一些丢失的数据,但是它只需要一个rerender,因为当我稍微滚动它时,数据就会出现。

    我用Redux来解决这个问题。在loginComponent按钮中,我发送一个action UPDATE\u RERENDER\u键,这由一个reducer处理,reducer切换属性,searchPage用 mapDStateToProps 那么,这难道不意味着searchComponent将在rerenderKey发生变化时重新加载吗?如何在rerenderkey发生更改时强制SearchQueryPage重新render?

    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 回复  |  直到 7 年前
        1
  •  1
  •   Haider Ali    7 年前

    我想你不需要一个卷轴来显示数据,我认为这是一个问题,它发生在我身上,而我正在使用平面列表,你可以通过添加这个来解决这个问题。

    removeClippedSubviews={false}

    推荐文章