-1

I am a React beginner.

I have a Parent component that has multiple input fields (InputField child component). OnFocus I want to toggle a child of Inputfield(InputFieldToolTip component) to show/hide from a method in the parent component

Currently, when I set the state of the showHide and pass into the Input field component via props, it toggles all the tooltip components

How do I reference an individual tooltip component in React? In jQuery, I would just give it an ID and use a Dom selector.

Example code (please don't take this as actual code, it's just a representative of the structure and what's being passed currently):

Parent Component

import React from 'react';
import ReactDOM from 'react-dom';
import InputField from './InputField.jsx';

class Parent extends React.Component {
  constructor(props){
    super(props);
    this.state={
        showHide: ' hide',
        toolTip: 'This is a tooltip'
    }

    this.showHide = this.showHide.bind(this);
 }
 showHide(){
    if(this.state.showHide === 'hide') {
        this.setState({
            showHide: 'show'
        ))};
    } else {
        this.setState({
            showHide: 'hide'
        });
    }

 }

render(){
    return(
      <div>
        <InputField
            name='input-1'
            OnFocus={this.showHide}
            type="text"
            showHide={this.state.showHide}
            toolTip={this.state.toolTip}
        />
        <InputField
            name='input-2'
            OnFocus={this.showHide}
            type="text"
            showHide={this.state.showHide}
            toolTip={this.state.toolTip}
        />
        <InputField
            name='input-3'
            OnFocus={this.showHide}
            type="text"
            showHide={this.state.showHide}
            toolTip={this.state.toolTip}
        />
     </div>
    )       

  }
}

InputField Component

import React from 'react';
import ReactDOM from 'react-dom';
import InputField from './ToolTip.jsx';

export class InputField extends React.Component{

 render(){
    return(
      <div>
        <Input/>
        <ToolTip
            showHide={this.props.showHide}
            toolTip={this.props.toolTip}
        />
     </div>
    )           
  }
}

ToolTip Component

import React, {Component} from 'react';
export const ToolTip = (props) => {
  return <div className={this.props.showHide}>{this.props.toolTip}</div>
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Barry Watts
  • 784
  • 2
  • 14
  • 43

1 Answers1

2

Your problem is that currently your state is shared by all your components. The showHide prop is the same for all inputs and tooltip components.

I assume the behavior you're going for is to have the corresponding tooltip show up when you focus an input.

You could do that by instead of having that state in your parent component, put it in each input/tooltip :

Parent

import React from 'react';
import ReactDOM from 'react-dom';
import InputField from './InputField.jsx';

class Parent extends React.Component {

 render(){
    return(
      <div>
        <InputField
            name='input-1'
            type="text"
            tooltipText="Input1 Tooltip"
        />
        <InputField
            name='input-2'
            type="text"
            tooltipText="Input2 Tooltip"
        />
        <InputField
            name='input-3'
            type="text"
            tooltipText="Input3 Tooltip"
        />
     </div>
    )       

  }
}

InputField

import React from 'react';
import ReactDOM from 'react-dom';
import InputField from './ToolTip.jsx';

export class InputField extends React.Component{

 constructor(props){
    super(props)
    this.state = {
       tooltipShown: false
    }
    this.showTooltip = this.showTooltip.bind(this)
    this.hideTooltip = this.hideTooltip.bind(this)
 }

 showTooltip(){
   this.setState({
     tooltipShown: true
   })
 }

 hideTooltip(){
   this.setState({
     tooltipShown: false
   })
 }

 render(){
    return(
      <div>
        <input onFocus={this.showTooltip} onBlur={this.hideTooltip} />
        <ToolTip 
          shown={this.state.tooltipShown} 
          text={this.props.tooltipText} 
        />
     </div>
    )           
  }
}

Tooltip

export const ToolTip = (props) => {
  return (
     <div className={props.shown ? 'show' : 'hide'}> 
       {props.tooltipText}
     </div>
  )
}

Now each InputField component controls its own Tooltip component. They can receive the tooltip's text as a prop and pass it down to the Tooltip. When you give focus to an InputField, it will tell the tooltip to be displayed, and when the focus is lost onBlur will trigger to hide it again.

Note that I also changed the Input in InputField to input as it doesn't seem like you're using a custom Input component.

Geoffrey H
  • 1,280
  • 2
  • 10
  • 33
  • Why you omit the `InputField` component? he wanna have a component for input with wrapping the `Tooltip`. the `show` and `hide` method can be one function. your code is not optimized. – AmerllicA Oct 16 '18 at 20:47
  • 1
    The `InputField` component is in my answer. I know it can be one function but there's no need to add confusion by adding unnecessary complexity. – Geoffrey H Oct 16 '18 at 20:58
  • You write a simple toggle show/hide function as two functions, this type of handwriting is complexity. I believe you change the face of this question. – AmerllicA Oct 16 '18 at 21:00