簡體   English   中英

如何在React-Native中重新呈現選項卡

[英]How to re-render a tab in React-Native

我有一個React-Native閃卡應用程序,它使用兩個選項卡,一個Home選項卡和一個New Deck選項卡啟動。 “主頁”選項卡是默認選項卡,您可以按或滑動到“新建工作區”選項卡。

  • “主頁”選項卡顯示用戶當前已保存的所有卡組。

  • 在New Deck選項卡上,我讓用戶輸入新牌組的標題並按下提交按鈕。 按下提交按鈕后,我將重新導航到“主頁”選項卡。

我的問題是 :如何通過New Deck選項卡上的按鈕按下主頁選項卡上的重新渲染,以便用戶可以看到他們剛剛創建的牌組?

我知道我可以使用Redux來解決這個問題,但是應用程序的其他任何部分都沒有以“Redux”的方式進行優化,我真的不想重新設計我的應用程序的架構,僅用於更新單個屏幕,主要是因為這是我需要這種能力的唯一例子。

我試圖通過從StackNavigator組件一直傳遞包含this.forceUpdate方法的screenProp來解決這個問題,但它沒有用。 我還嘗試手動更新App組件的狀態以觸發重新渲染,但重新渲染從未發生過(盡管狀態確實更新了)。

App.js

import React, { Component } from 'react'
import { Text, View } from 'react-native'
import AlphaHome from './Components/Home/AlphaHome'
import AlphaQuiz from './Components/Quiz/AlphaQuiz'
import AlphaNewUdaciDeck from './Components/NewUdaciDeck/AlphaNewUdaciDeck'
import AlphaNewUdaciCard from './Components/NewUdaciCard/AlphaNewUdaciCard'
import AlphaUdaciDeckDetails from './Components/UdaciDeckDetails/AlphaUdaciDeckDetails'
import { TabNavigator, StackNavigator } from 'react-navigation'

const Tabs = TabNavigator({
  Home: {
    screen: AlphaHome,
    navigationOptions: {
      tabBarLabel: 'Home',
    },
  },
  NewDeck: {
    screen: AlphaNewUdaciDeck,
    navigationOptions: {
      tabBarLabel: 'New Deck',
    }
  }
}, {
  navigationOptions: {
    header: null,
  },
  tabBarOptions: {
    activeTintColor: 'white',
    indicatorStyle: {
      backgroundColor: 'white'
    },
    style: {
      height: 50,
      borderBottomColor: 'white',
      backgroundColor: 'deepskyblue',
    }
  },
})

const Stack = StackNavigator({
  Home: {
    screen: Tabs,
  },
  AlphaNewUdaciDeck: {
    screen: AlphaNewUdaciDeck,
    navigationOptions: {
      headerTintColor: 'white',
      headerStyle: {
        backgroundColor: 'deepskyblue'
      }
    }
  },
  AlphaNewUdaciCard: {
    screen: AlphaNewUdaciCard,
    navigationOptions: {
      headerTintColor: 'white',
      headerStyle: {
        backgroundColor: 'deepskyblue'
      }
    }
  },
  AlphaUdaciDeckDetails: {
    screen: AlphaUdaciDeckDetails,
    navigationOptions: {
      headerTintColor: 'white',
      headerStyle: {
        backgroundColor: 'deepskyblue'
      }
    }
  },
})

export default class App extends Component {
  render() {
    return (
      <Stack />
    )
  }
}

Home.js

import React, { Component } from 'react'
import { ScrollView, View, Text, StyleSheet, AsyncStorage, ActivityIndicator } from 'react-native'
import UdaciDeck from '../Reusable/UdaciDeck'
import { getAllData } from '../../utils/AsyncApi'

export default class HomeExistingUser extends Component {
  state = {
    decks: null,
  }
  componentDidMount() {
    let decks = getAllData()
    setTimeout(() => {
      this.setState({
        decks
      })
    }, 1000)
  }
  showDetails = (title, count) => {
    this.props.navigation.navigate('AlphaUdaciDeckDetails', {title, count})
  }
  render() {
    const {decks} = this.state
    return (
      decks
      ? <ScrollView contentContainerStyle={styles.container}>
            {decks.map(s => <UdaciDeck key={s[1].title} name={s[1].title} count={s[1].questions.length} method={this.showDetails} />)}
        </ScrollView>
      : <View style={[styles.container, {flex: 1, justifyContent: 'center'}]}>
          <ActivityIndicator size='large' color='white' />
        </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    minHeight: '100%',
    backgroundColor: 'lightskyblue',
    paddingTop: 20,
    paddingBottom: 20,
    alignItems: 'center',
  },
})

NewDeck.js

import React, { Component } from 'react'
import { View, Text, TextInput, StyleSheet, AsyncStorage, TouchableNativeFeedback, Alert } from 'react-native'
import { addDeck } from '../../utils/AsyncApi'

// BUG: when adding a new deck (if HomeExistingUser is true) view doesn't update. Need to figure out a way to update on tab navigate back

export default class AlphaNewUdaciDeck extends Component {
  state = {
    input: '',
    keys: null,
  }
  componentDidMount() {
    AsyncStorage.getAllKeys()
      .then(keys => this.setState({
        keys
      }))
  }
  handleSubmit = () => {
    const {input, keys} = this.state
    input.search(' ') > 0 || input.length < 1 || keys.filter(s => s === input).length > 0
      ? Alert.alert(`Please enter a valid name (${input.length < 1 || keys.filter(s => s === input).length > 0 ? `you can't save a deck with ${input.length < 1 ? 'no' : 'an already used'} name` : "no spaces"})`)
      : addDeck(input)
    ;if(input.search(' ') < 0 || input.length > 0 || keys.filter(s => s === input).length < 1) {
      this.props.navigation.goBack()
    }
  }
  render() {
    return (
      <View style={[styles.container, styles.containerOne]}>
         <View style={styles.containerTwo}>
            <Text style={styles.text}>Name of the deck</Text>
            <Text style={styles.text}>(Please no spaces)</Text>
            <TextInput
              autoFocus={true}
              onChangeText={(input) => this.setState({
                input
              })}
              selectionColor={'deepskyblue'}
              underlineColorAndroid={'transparent'}
              style={styles.input}
            />
            <TouchableNativeFeedback onPress={this.handleSubmit}>
              <View style={styles.btn}>
                <Text style={styles.btnText}>Save Deck</Text>
              </View>
            </TouchableNativeFeedback>
          </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'lightskyblue',
  },
  containerOne: {
    alignItems: 'center',
  },
  containerTwo: {
    marginTop: 50,
  },
  text: {
    color: 'white',
    fontSize: 20,
  },
  input: {
    backgroundColor: 'white',
    height: 50,
    width: 300,
    marginTop: 15,
    fontSize: 20,
    paddingLeft: 5,
    paddingRight: 5,
    color: 'deepskyblue'
  },
  btn: {
    backgroundColor: 'deepskyblue',
    marginTop: 50,
    padding: 20,
    paddingLeft: 50,
    paddingRight: 50,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 5,
  },
  btnText: {
    color: 'white',
  },
})

您應該訪問https://github.com/pmachowski/react-navigation-is-focused-hoc查看react-navigation-focus-hoc,以解決您提到的具體問題。

你也可以試試

onNavigationStateChange(prevState, newState) 

有一個示例如何判斷屏幕是否通過ReactNavigation導航到

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM