I want to pass a function from parent to child's child component, but showing up as 'undefined'
I understand how to pass function from parent to child:
class Child extends Component {
render() {
<div onClick={this.props.passedFunction}></div>
}
}
class Parent extends Component {
passedFunction = () => {}
render() {
<Child passedFunction={this.passedFunction}/>
}
}
(Reference: past question)
But how do I properly pass down to the GrandChild in this:
class GranChild extends Component {
render() {
<div onClick={this.props.passedFunction}></div>
}
}
class Child extends Component {
render() {
<GranChild passedFunction={this.passedFunction}/>
}
}
class Parent extends Component {
passedFunction = () => {}
render() {
<Child passedFunction={this.passedFunction}/>
}
}
refactor your child function to this:
class Child extends Component {
render() {
<GranChild passedFunction={this.props.passedFunction}/>
}
}
Related
How to access Parent's props in the Child's tag and function sayhello?
(I can access siblings and children without passing props as an argument but not the parent)____________________________________________
And (away from this example) If this refers to Parent, how to access Child's props?
And if this refers to Child as an html tag, is there a function to convert the result into the react component class? (not reassigning this as the class to a new variable () => instead of function())
Child:
class Child extends Parent{
constructor(props){
super(props);
}
render() {
return (
<p>{Parent.props.hello}</p> // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<button onClick={sayhello.bind(this)}></button> // <<<<<<<<<<<<<<<<<<<<<<<<
);
}
}
Parent:
class Parent extends React.Component{
constructor(props){
super(props);
}
render() {
<>
<Child/>
</>
}
}
sayhello:
function sayhello(){
console.log(Parent.props); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
If you bind the function in component, you can refer to this.props:
class Child extends React.Component {
render() {
return (
<>
<button onClick={sayhello.bind(this)}>Click</button>
</>
);
}
}
class Parent extends React.Component {
render() {
return (
<>
<Child someProp="hello" />
</>
);
}
}
function sayhello() {
console.log(this.props);
}
I have a React component that I exported it like this:
class Child extends Component {
getStatus() {
return 'I am child!';
}
render() {
return (<div>Child</div>);
}
}
export default withRouter(Child)
And I have another class that needs the ref of "Child" component like this:
class Parent extends Component {
constructor(props) {
super(props);
this.childRef = createRef();
}
handleLogChildStatus = () => {
if (typeof this.childRef.current.getStatus === 'function') {
console.log(this.childRef.current.getStatus());
} else {
console.log(' Can not access to child component via ref! ');
}
}
render() {
return (
<div>
<Child ref={this.childRef} />
<div onClick={this.handleLogChildStatus}>Log child status</div>
</div>
);
}
}
This sample shows me I can not access to child component ref because it wrapped by withRouter HOC.
My question is How I can access to child ref component when it wrapped by nextjs withRouter>
I think one of below should work
export default withRouter(Child, { withRef: true })
2nd option
this.childComponent = React.createRef();
....
<Child wrappedComponentRef={c => (this.childComponent = c)} />
I know I can access a ref for the child like so
ParentComponent extends React.Component {
constructor() {
this.myRef = React.createRef();
}
render() {
return (
<ChildComponent>
<div ref={myRef}>Blah</div>
<ChildComponent>
);
}
}
ChildComponent extends React.Component {
render() {
const {children} = this.props.children;
console.log(children.ref) // Will get DOM element
return {children}
}
}
But is there a way to get the DOM element without passing in the ref from the parent component so that my child component can get the ref from this.props.children?
At a high level i'm trying to make an extensible component ChildComponent so that every parent component that uses ChildComponent doesn't have to declare refs for the child component.
Found an answer here Getting DOM node from React child element
The answer is slightly old so I rewrote a bit of it with callback refs instead of using findDOMNode (https://github.com/yannickcr/eslint-plugin-react/issues/678).
ParentComponent extends React.Component {
constructor() {
this.myRef = React.createRef();
}
render() {
return (
<ChildComponent>
<div ref={myRef}>Blah</div>
<ChildComponent>
);
}
}
ChildComponent extends React.Component {
constructor() {
this.myElement = null;
this.myRef = element => {
this.myElement = element;
};
}
render() {
const {children} = this.props.children;
return (
<div>
{React.cloneElement(children, { ref: this.myRef})};
</div>
)
}
}
Note: the above only works with child component only having child from parent
I want to get ref of Child component. What is the best way to do this?
class Child extends React.Component {
render() {
return <div>Child</div>;
}
}
class GetRef extends React.Component {
componentDidMount() {
console.log(this.props.children.ref)
}
render() {
return this.props.children
}
}
Edit:
So I can use it like this
<GetRef><Child/></GetRef>
I assumed that GetRef children has only one child, then you can retrieve the ref of the only child component with this code
class Child extends React.Component {
render() {
return <div>Child</div>;
}
}
class GetRef extends React.Component {
componentDidMount() {
console.log(this.ref);
}
render() {
const childElement = React.Children.only(this.props.children);
return React.cloneElement(
childElement,
{ ref: el => this.ref = el }
);
}
}
class App extends Component {
render() {
return <GetRef><Child/></GetRef>;
}
}
Here is the complete example on stackblitz
If this.props.children has more than one child, you will need to iterate over the children and store all the refs into an array
This is where forwardRef can be used:
class GetRef extends React.Component {
render() {
console.log(this.props.forwardRef)
}
}
const ref = React.createRef();
<Child forwardRef={ref} />
Alternatively, you may also use:
<Child ref="childRef" .../>
// In the parent component
React.findDOMNode(this.refs.childRef)
But take a look at Exposing DOM Refs to Parent Components to know whether to use ref or not:
In rare cases, you might want to have access to a child’s DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.
Say you have a parent component:
// ParentComponent
class ParentComponent extends React.Component {
render() {
return(
<ChildComponent/>
)
}
}
From inside the child component, is there a way to access the class name of the parent component without passing this down as props?
// ChildComponent
class ChildComponent extends React.Component {
// ?????
getParentComponentName() {
return this.??? // Should return "ParentComponent"
}
render() {
return(
<div/>
)
}
}
I'd prefer to be able to access this without passing it down as props. Thank you!
You need to access ReactInternalFiber like
class Child extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' }
}
getParentName = () =>{
this.setState({ name: this._reactInternalFiber._debugOwner.type.name })
}
render() {
return (
<div>
<h1>Name: {this.state.name}</h1>
<button onClick={this.getParentName}>Get Parent Name</button>
</div>
)
}
}