jbone107
jbone107

Reputation: 156

Refs are always null inside modal component

All refs created inside the reactstrap modal component are null inside compoenentDIDMount no matter how they are created

This is related to react-dom version 16.8.6. I have tried assigning ref directly, using react.createRef(), and callbacks.

import { Modal, Form } from 'reactstrap'

class QuickBidModal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          isOpen: false,
        };
        this.input1 = React.createRef();
    }

componentDidMount(){
  console.log(this.input1) //Always returns current as null
}

render(){
 <Modal>
  <Form>
  <div className="input" ref={this.input1} />
  </Form>

 </Modal>
}

I expect this.input1 to be of class input on the current property. However, it only returns null. If I create the div element OUTSIDE of the Modal component, then the ref works properly.

Upvotes: 1

Views: 3885

Answers (2)

Saqy G
Saqy G

Reputation: 806

Method provided by @Ayush singh is more like a hack. The correct way to implement is use Callback hook. Whenever the component will render you will have the ref element. useCallback will also help stop unnecessary renders hence better performance.

const Parent = () => {
  const [isVisible, setIsVisible] = useState(false);
  return (
    <>
      <button onClick={() => setIsVisible(!isVisible)}>Show/Hide Popup</button>
      <Child isVisible={isVisible} />
    </>
  );
};

const Child = () => {
  const customRef = useCallback((ref) => {
    // ref element accessible here
  }, []);
  return (
    <Modal show={isVisible}>
      <Modal.Body>
        <input ref={customRef} type="text" />
      </Modal.Body>
    </Modal>
  );
};

Upvotes: 3

Ayush Singh
Ayush Singh

Reputation: 126

useRef hook will not work in modals as the component will mount but the jsx will not render until you make show prop to true. useRef is asynchronous in nature thats why at the time of declaration it sets current to null but after you assign it to any element ref got value of it. But in case of modals the case is different. Here the elements are not registered instantly but after modal show prop is set to true

To solve this make the modal's show prop always to true and make whole component to show/hide dynamically. eg.

const Child=()=>{
  const customRef=useRef(null);
  return(
     <Modal show={true}>
       <Modal.Body>
         <input ref={customRef} type="text"/>
       </Modal.Body>
    </Modal>
   );
}

const Parent=()=>{
   const [show,setShow]=useState=(false)
   return(
       <>
         <button onClick={()=>setShow(!show)}>Show/Hide Popup</button>
         {
           show?<Child/>:null
         }
       </>
   )
  }

Upvotes: 1

Related Questions