Queen
Queen

Reputation: 571

React.Children.only expected to receive a single React element child error while using Ref

I have to call some methods from component B inside component A. Here is the component B: (In the case that you need more code just request me and I will update my post)

import A  from "./A";
export default class B extends Component {
  componentDidUpdate (prevProps, prevState) {
    this.props.onRef(this);
  }

  renderContent ( ) {
    let toolbarActiveItem = Toolbar.getActiveItem();
    if (Toolbar.getActiveItem()=="XXXX") {
      this.refs.A._showModalHistory();
    } else {
      toolbarActiveItem = Toolbar.getActiveItem();
    }

    return (
      <Container>
        {(toolbarActiveItem == 'YYY') && <C navigation={this.props.navigation} cb={this.childCallback} info={this.props.navigation.state.params}/> }
      </Container>
    );
  }

  render () {
    return (
      <StyleProvider style={getTheme(Config.theme)}>
        <A ref={component => { this.A = component; }} />
        <Container ref={this.ref}>
          { this.renderNavbar(this.title) }
          { this.renderToolbar() }
          { this.renderContent() }
          { this.renderDialog() }
        </Container>
      </StyleProvider>
    );
  } 

Here is the component A:

export default class A extends Component {
  constructor(props) {
    super();
    this.subscription = 0;
    this.state = {};
    changePage = props.cb;

    this.state = {
      isModalVisibleHistory: false,
    };
  }

  _showModalHistory = () => this.setState({ isModalVisibleHistory: true });

  render() {
    return (
      <Modal isVisible={this.state.isModalVisibleHistory}>
        <View style={styles.BG}>
        <ParkHistory></ParkHistory>
        </View>
      </Modal>
    );
  }
}

My problem is that, I need to execute this.refs.A._showModalHistory(); in component B but, I see the following error:

React.Children.only expected to receive a single React element child.

I think, I have a problem to deal with rendering multiple components and ref them. I should mention that, when I delete <A ref={component => { this.A = component; }} /> my code works fine but, without calling the method. Could you please help me to solve this issue?

Upvotes: 1

Views: 997

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281774

The problem is in the way you are accessing the ref. You have assigned ref to Component A. You are using the callback style to assign ref and so you need not write this.ref.A. Change it to this.A._showModalHistory();

Aslo the way you are setting ref to Container component is incorrect, you need to use callback there

<Container ref={(ref)=> this.ref = ref}>

One other thing is that the StyleProvider component expects a single child element. You should wrap your Container and A component in View

render () {
    return (
      <StyleProvider style={getTheme(Config.theme)}>
        <View>
        <A ref={component => { this.A = component; }} />
        <Container ref={(ref)=> this.ref = ref}>
          { this.renderNavbar(this.title) }
          { this.renderToolbar() }
          { this.renderContent() }
          { this.renderDialog() }
        </Container>
        </View>
      </StyleProvider>
    );
  } 

Upvotes: 1

Related Questions