【问题标题】:React Native - Can I pass state objects to child component from parent?React Native - 我可以将状态对象从父组件传递给子组件吗?
【发布时间】:2018-11-30 07:47:42
【问题描述】:

React Native 新手。 我正在创建一个注册表单,其中我创建了一个表单向导,每个步骤都有一个不同的组件。我想处理来自父组件的每个输入的状态。

错误:

 Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Objects are not valid as a React child (found:
 object with keys {_40, _65, _55, _72}). If you meant to render a
 collection of children, use an array instead.
     in RCTView (at View.js:45)
     in RCTScrollView (at ScrollView.js:977)
     in ScrollView (at KeyboardAwareHOC.js:397)
     in _class (at Content.js:125)
     in Content (at connectStyle.js:384)
     in Styled(Content) (at RegisterBusiness.js:271)
     in RCTView (at View.js:45)
     in Container (at connectStyle.js:384)
     in Styled(Container) (at RegisterBusiness.js:242)
     in RegisterBusiness (at SceneView.js:9)
     in SceneView (at StackViewLayout.js:478)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AnimatedComponent (at screens.native.js:58)
     in Screen (at StackViewCard.js:42)
     in Card (at createPointerEventsContainer.js:26)
     in Container (at StackViewLayout.js:507)
     in RCTView (at View.js:45)
     in ScreenContainer (at StackViewLayout.js:401)
     in RCTView (at View.js:45)
     in StackViewLayout (at withOrientation.js:30)
     in withOrientation (at StackView.js:49)
     in RCTView (at View.js:45)
     in Transitioner (at StackView.js:19)
     in StackView (at createNavigator.js:57)
     in Navigator (at createKeyboardAwareNavigator.js:11)
     in KeyboardAwareNavigator (at createNavigationContainer.js:376)
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at DrawerView.js:87)
     in RCTView (at View.js:45)
     in AndroidDrawerLayout (at DrawerLayoutAndroid.android.js:205)
     in DrawerLayoutAndroid (at DrawerView.js:84)
     in DrawerView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at SwitchView.js:12)
     in SwitchView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at App.js:135)
     in RCTView (at View.js:45)
     in Root (at connectStyle.js:384)
     in Styled(Root) (at App.js:134)
     in App (at renderApplication.js:34)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AppContainer (at renderApplication.js:33)

 This error is located at:
     in RCTView (at View.js:45)
     in RCTScrollView (at ScrollView.js:977)
     in ScrollView (at KeyboardAwareHOC.js:397)
     in _class (at Content.js:125)
     in Content (at connectStyle.js:384)
     in Styled(Content) (at RegisterBusiness.js:271)
     in RCTView (at View.js:45)
     in Container (at connectStyle.js:384)
     in Styled(Container) (at RegisterBusiness.js:242)
     in RegisterBusiness (at SceneView.js:9)
     in SceneView (at StackViewLayout.js:478)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AnimatedComponent (at screens.native.js:58)
     in Screen (at StackViewCard.js:42)
     in Card (at createPointerEventsContainer.js:26)
     in Container (at StackViewLayout.js:507)
     in RCTView (at View.js:45)
     in ScreenContainer (at StackViewLayout.js:401)
     in RCTView (at View.js:45)
     in StackViewLayout (at withOrientation.js:30)
     in withOrientation (at StackView.js:49)
     in RCTView (at View.js:45)
     in Transitioner (at StackView.js:19)
     in StackView (at createNavigator.js:57)
     in Navigator (at createKeyboardAwareNavigator.js:11)
     in KeyboardAwareNavigator (at createNavigationContainer.js:376)
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at DrawerView.js:87)
     in RCTView (at View.js:45)
     in AndroidDrawerLayout (at DrawerLayoutAndroid.android.js:205)
     in DrawerLayoutAndroid (at DrawerView.js:84)
     in DrawerView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at SwitchView.js:12)
     in SwitchView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at App.js:135)
     in RCTView (at View.js:45)
     in Root (at connectStyle.js:384)
     in Styled(Root) (at App.js:134)
     in App (at renderApplication.js:34)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AppContainer (at renderApplication.js:33)

 This error is located at:
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at DrawerView.js:87)
     in RCTView (at View.js:45)
     in AndroidDrawerLayout (at DrawerLayoutAndroid.android.js:205)
     in DrawerLayoutAndroid (at DrawerView.js:84)
     in DrawerView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at SwitchView.js:12)
     in SwitchView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at App.js:135)
     in RCTView (at View.js:45)
     in Root (at connectStyle.js:384)
     in Styled(Root) (at App.js:134)
     in App (at renderApplication.js:34)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AppContainer (at renderApplication.js:33)

 This error is located at:
     in NavigationContainer (at SceneView.js:9)
     in SceneView (at SwitchView.js:12)
     in SwitchView (at createNavigator.js:57)
     in Navigator (at createNavigationContainer.js:376)
     in NavigationContainer (at App.js:135)
     in RCTView (at View.js:45)
     in Root (at connectStyle.js:384)
     in Styled(Root) (at App.js:134)
     in App (at renderApplication.js:34)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AppContainer (at renderApplication.js:33)

 This error is located at:
     in NavigationContainer (at App.js:135)
     in RCTView (at View.js:45)
     in Root (at connectStyle.js:384)
     in Styled(Root) (at App.js:134)
     in App (at renderApplication.js:34)
     in RCTView (at View.js:45)
     in RCTView (at View.js:45)
     in AppContainer (at renderApplication.js:33) throwOnInvalidObjectType

父组件:Register.js

constructor() {
    super();
    this.state = {
        pageCount: 1,
        pageName : 'merchantReg',
        stepName: "Basic Details",
        merchantReg: {
          contactperson: "STAR",
          contactno: "1234567890",
          altcontactno: "",
          email: "",
          altemail: "",
          legalname: "",
          dbaname: "",
          typeofpos: "NA",
          noofpos: "0",
          pacakage: "NA",
          natureofbusiness: "NA",
        },
        businessReg : {
          businessType: "",
          gststatus:"",
          gstno:"",
          panno:"",
          tinno:"",
          shopno:"",
          salestaxno:"",
          officepremisis:"",
          currentlocation:"",
          businesslastyear:"",
          averagebillamt:"",
          expectedcardbusiness:"",
        },
        residenceaddress:"",
        bankDetails : {
          bankname:"",
          bankbranch:"",
          accountname:"",
          accountno:"",
          ifsccode:"",
          aadharno:"",
          posstatement:"",
          posfirc:"NA",
          fircfreq:"NA",
        },
        mdr:{
          debitcardpremium:"",
          debitcardclassic:"",
          creditcardclassic:"",
          creditcardpremium:"",
          foreigncard:"",
          terminal_service_fee:"",
          terminal_type:"",
          posamount:""
        }
    }
 }


_storetoState = (key1,value) => {
  var page = this.state.pageName;
  this.setState({
    [page]: {
          ...this.state[page],
          [key1] : value
    }
  })
}

StepsofRegistrations = async () => {
  switch(this.state.pageCount){
    case 1: {

        requiredFields = [];
        requiredFields.push('contactperson','contactno','email','legalname','dbaname','typeofpos');
        return (<MerchantRegister value={this.state.merchantReg} handleChange={this._storetoState} />);
        break;
    }
    case 2: {
        requiredFields = [];
        requiredFields.push('contactperson','contactno','email','legalname','dbaname','typeofpos');
        return(<ShopDetails  value={this.state.businessReg} handleChange={this._storetoState}/>);
        break;
    }

  }
}


  render() {
    return (
      <Container>
        <Header noShadow>
          <Left>
            <Button transparent onPress={() => this.props.navigation.goBack()}>
              <Icon name='arrow-back'/>
            </Button>
          </Left>
          <Body>
            <Title style={{
              width: 215
            }}>
              Register a New Business
            </Title>
          </Body>
          <Right></Right>
        </Header>

          <View style={{
              paddingHorizontal:30,
              padding:10,
              backgroundColor:'#eee',
              flexDirection:'row',
              justifyContent:'space-between',
              elevation:1
            }}>
              <View><Text style={{fontSize:18}}>{this.state.stepName}</Text></View>
              <View><Text style={{fontSize:17,textAlign:'right'}}>{this.state.pageCount}/6</Text></View>
            </View>

        <Content>

          <View style={{
            borderWidth:0.2,
            borderColor:'#ccc',
          }}></View>

            {this.StepsofRegistrations()}


        </Content>

      </Container>
    );
  }

一个我的子组件我的所有其他组件都与下面的代码相同,它们只是更改了名称。

import React, {Component} from 'react';
import { View, Text, StyleSheet, AsyncStorage, ScrollView } from 'react-native';
import { Picker, Label, Item, Input, Icon } from 'native-base';
import PropTypes from 'prop-types'

class MerchantRegister extends Component {

  render() {

    return (
      <ScrollView style={{
        paddingHorizontal: 30,
        paddingVertical: 20
      }}>

        <View style={{
          marginVertical: 10
        }}>

          <Label
            style={{
            fontSize: 14,
            marginBottom: 10
          }}>
            Contact Person
          </Label>
          <Item regular>
            <Input value={this.props.value.contactperson} onChangeText={value => this.props.handleChange("contactperson",value)}/>
          </Item>
        </View>

        </View>
      </ScrollView>
    );
  }
}



MerchantRegister.propTypes = {
  value: PropTypes.object.isRequired,
}

export default MerchantRegister;

每当我从注册组件中删除 {this.StepsofRegistrations()} 时,它都可以正常工作,但是当我从 {this.StepsofRegistrations()} 这个函数中删除所有内容时,这仍然会给我错误。

【问题讨论】:

  • 您能否更准确地显示您将道具传递给子组件的位置?我还注意到您的 MerchantRegister Class 组件没有 constructor() 函数和调用 super(props) 如果您想在孩子中使用道具,这是必要的。对于这种复杂的状态,我建议您考虑使用 ReduxContext API 仅在需要时共享状态,并避免在每个级别传递它。
  • return (&lt;MerchantRegister value={this.state.merchantReg} handleChange={this._storetoState} /&gt;); 这是我将状态作为值传递的地方
  • 在这里我作为道具访问状态&lt;Input value={this.props.value.contactperson} onChangeText={value =&gt; this.props.handleChange("contactperson",value)}/&gt;
  • 至少从 _storeToState 中删除异步内容,那里不需要。否则,您的模式与我使用的非常相似。
  • @RomanBatsenko 我已经分享了完整的错误代码,你现在可以检查一下吗

标签: javascript reactjs react-native


【解决方案1】:

this.StepsofRegistrations() 中删除异步对我有用。 但更多信息您可以查看:https://stackoverflow.com/a/37997990/4315757

【讨论】:

  • 一般评论是,只有当您真正调用返回 Promises 的函数(http 请求、数据库请求等)时,您才需要异步调用。当您在本地使用您的应用程序时,您通常不需要做任何这些。
猜你喜欢
  • 2022-07-15
  • 2017-12-06
  • 2019-02-17
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 2019-04-02
相关资源
最近更新 更多