Reputation: 156
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
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
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