Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - passing refs as a prop

Tags:

reactjs

I am trying to manage a checkbox with react. The following code works well enough, but I want to refactor out the code in the render method so that it uses a Component. I want to pass the ref to that component, but I cant figure out how to do it.

export default class AreRefsAwesomeCheckbox extends Component {
    constructor(props) {
        super(props);
        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange() {
        let data = {
            isFeatured: this.refs.check_me.checked
        };
        postJSON('/some/url', data);
    }


    componentDidMount() {
        const data = getJSON('/some/url');
        data.then(object => {
                this.refs.check_me.checked = object.will_i_have_a_nice_checkbox;
            }
        )
    }

    render() {
        return (
            <div>
                <label>
                    <input ref="check_me" type="checkbox" 
                           onChange={this.handleInputChange}/>
                    <div>Are refs good?</div>
                </label>

            </div>
        );
    }
}

I was thinking about some thing like this

const Checkbox = ({myRef, changeInput, checkboxText}) => {
    return (
        <label>
            <input type="checkbox" ref={myRef} onChange={(event) => changeInput(event)}/>
            <div> {checkboxText} </div>
        </label>)
};

And then putting this snippet in the render method

<Checkbox myRef="check_me" changeInput={this.handleInputChange} checkboxText="Are refs good?"/>

This obviously doesnt work. How do I do this?

like image 406
Ryan Avatar asked Dec 08 '17 17:12

Ryan


People also ask

Can Ref be passed as Prop React?

There is one caveat to the above example: refs will not get passed through. That's because ref is not a prop. Like key , it's handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component.

How do you pass REF IN React?

React will pass the ref through and forward it down to <input ref={ref}> by specifying it as a JSX attribute. When the ref is attached, ref. current will point to the <input> DOM node. The second ref argument in the InputRef component only exists when you define a component with React.

How do you pass ref to the functional component?

To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.


2 Answers

Pass a callback ref into the Component, like that:

<Checkbox myRef={ref => (this.checkbox = ref)} />

Oh, and by the way, please always use callback refs. Read more here.

One more idea to consider for you: Move the checked value of the checkbox fully into the state of the AreRefsAwesomeCheckbox component and use a fully controlled component. That's always better than a ref with bigger predictability and less surprises.

Full code:

const Checkbox = ({myRef, changeInput, checkboxText}) => {
  return (
    <label>
      <input
        type="checkbox"
        ref={myRef}
        onChange={event => changeInput(event)}
      />
      <div> {checkboxText} </div>
    </label>
  )
}

export default class AreRefsAwesomeCheckbox extends Component {
  constructor(props) {
    super(props)
    this.handleInputChange = this.handleInputChange.bind(this)
  }

  handleInputChange() {
    let data = {
      isFeatured: this.refs.check_me.checked,
    }

    postJSON('/some/url', data)
  }

  componentDidMount() {
    const data = getJSON('/some/url')
    data.then(object => {
      // this.checkbox is the reference to the checkbox element you need
      this.checkbox.checked = object.will_i_have_a_nice_checkbox
    })
  }

  render() {
    return (
      <div>
        <label>
          <Checkbox myRef={ref => (this.checkbox = ref)} />

          <div>Are refs good?</div>
        </label>
      </div>
    )
  }
}
like image 177
Andrei Glingeanu Avatar answered Oct 24 '22 10:10

Andrei Glingeanu


Use createRef to create the ref that you end up passing down.

If you're passing a ref to a function component use React.forwardRef.

If you're passing a ref down to a class component ensure that the prop name is anything except ref or you'll get a special prop warning.

like image 30
IliasT Avatar answered Oct 24 '22 11:10

IliasT