簡體   English   中英

反應本機,狀態更改,但組件無法正確渲染

[英]React Native, State Changes, but Component Does not Properly Render

我正在開發我的第一個React Native應用程序,但是對React和React Native感到非常滿意,這讓我感到驚訝。

目標-允許用戶根據他們的輸入需求動態創建選項卡。 每個選項卡都重復使用作為表單的相同組件。 按下時,選項卡應顯示其對應的表格。 該表格工作正常。

問題-父組件在按Tab鍵時無法呈現正確的表單。 狀態會更新,但組件仍保留在所選的第一個組件上。 如果我在一個屏幕上一個接一個地列出表單,我可以看到填寫一個表單對其他表單沒有影響(期望的效果)。

如果我不渲染表單組件,它將在第一次按下Tab鍵時起作用。 這使我想知道React是否不在父組件中注冊更改,因為子組件始終是我希望顯示的其他子組件的副本。

我沒有運氣就以三種方式解決了這個問題。

  1. 創建存儲在父組件狀態中的組件數組。 創建一個新的選項卡可以通過抓住一個數組,將一個組件推入該組件並使用該新數組重置狀態來將表單組件推入當前數組。 我將按鍵存儲在屏幕上更新的狀態中。 該鍵與組件數組中的索引匹配,以顯示選定的組件及其相應的選項卡。

  2. 使用componentDidUpdate來設置屏幕上顯示的組件,方法與上面類似,但不是在我的渲染函數中鍵入數組,而是在componentDidUpdate函數中手動在組件的每次更新上設置了displayView並在渲染中使用它。

  3. 當前(以下代碼)-為添加的每個選項卡在狀態下創建唯一鍵,這些鍵存儲相應的組件,並使用該鍵來解密要顯示的組件。

我決定在一些子組件上添加參考。 我在渲染之前使用console.log查看是否選擇了正確的組件進行顯示。 它顯示了,但是沒有以這種方式出現在屏幕上。 我還向用戶界面添加了被單擊的選項卡編號,每次按選項卡時,我都可以看到狀態正確更新。

任何幫助,將不勝感激。 不得已時,我要讓用戶在到達此視圖之前選擇所需的表單數量並根據該數量創建它,但我不希望這樣做。

import React from 'react';
import { connect } from 'react-redux';
import { View, Text, TouchableOpacity } from 'react-native';
import CreateWorkoutSet from './CreateWorkoutSet';
import { Entypo } from '@expo/vector-icons';

class CreateWorkout extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      workoutSetTemplate0: <CreateWorkoutSet navigation={this.props.navigation}/>,
      showTab: 0,
      totalTabs: 0,
    }

    this.addWorkoutSetToGroup = this.addWorkoutSetToGroup.bind(this)
  }

  componentDidMount() {
    this.setState({
      tabs: [
        <TouchableOpacity onPress={() => this.setState({ showTab: 0 })}>
          { this.state.showTab === 0 ? (
            <View style={{ backgroundColor: 'red', height: 40, width: 40 }}>
              <Text>Tab: 1</Text>
            </View>
          ) :
            <View style={{ backgroundColor: 'grey', height: 40, width: 40 }}>
              <Text>Tab: 1</Text>
            </View>
          }
        </TouchableOpacity>
      ],
      showTab: 0
    })
  }

  addWorkoutSetToGroup() {
    let tabNumber = this.state.totalTabs + 1 
    let tabKey = `workoutSetTemplate${tabNumber}` 
    let tabs = this.state.tabs 
    tabs.push(
      <TouchableOpacity onPress={() => this.setState({ showTab: tabNumber })}>
        { this.state.showTab === tabNumber ? (
          <View style={{ backgroundColor: 'red', height: 40, width: 40 }}>
            <Text>Tab: {tabNumber}</Text>
          </View>
        ) : 
          <View style={{ backgroundColor: 'grey', height: 40, width: 40 }}>
            <Text>Tab: {tabNumber}</Text>
          </View>
        }
      </TouchableOpacity>
    )
    this.setState({ [tabKey]: <CreateWorkoutSet navigation={this.props.navigation} />, tabs: tabs, totalTabs: tabNumber })
  }

  render() {
    let template = this.state[`workoutSetTemplate${this.state.showTab}`]
    let tabs = this.state.tabs
    return(
      <View style={{flex: 1, justifyContent: 'center', marginTop: 20}}>
        <View style={{ flexDirection: 'row' }}>
          {tabs}
        </View>
        <View>
          <Text>Add Exercise To Group</Text>
          <TouchableOpacity onPress={()=> this.addWorkoutSetToGroup()}>
            <Entypo name='circle-with-plus' size={36} color='red' />
          </TouchableOpacity>
        </View> 
        <TouchableOpacity onPress={() => this.props.navigation.navigate('BlockDetail')}>
          <Text>Blocks</Text>
        </TouchableOpacity>
        <Text>{this.state.showTab}</Text>
        {template}
      </View>
    )
  }
}

export default connect()(CreateWorkout)

嘗試致電

this.forceUpdate()

更新狀態后

暫無
暫無

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

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