Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't call child method using a ref with connect

I would like to call a method from a child component, as per suggested here Call child method from parent

However, it doesn't work when the child component is wrapped with connect from react-redux as in the example below:

Child Component

interface OwnProps {
  style?: any;
}
interface ReduxStateProps {
  category: string;
}
interface DispatchProps {
  updateTimestamp: (timestamp: Date) => void;
}
type Props = ReduxStateProps & DispatchProps & OwnProps;

interface State {
  timestamp?: Date;
}

class ChildComponent extends React.Component<Props, State> {
  childMethod = () => {
    console.log("I am the child");
  };

  render(){
      <Text>Debug</Text>
  }
}

function mapStateToProps(state: any): ReduxStateProps {
  return {
    category: state.menu.category
  };
}

function mapDispatchToProps(dispatch: Dispatch<any>): DispatchProps {
  return {
    updateTimestamp: (timestamp: Date) =>
      dispatch(updateTimestampActionCreator(timestamp))
  };
}

export default connect<ReduxStateProps, DispatchProps, OwnProps>(
  mapStateToProps,
  mapDispatchToProps
)(ChildComponent);

Parent Component

class ParentComponent extends React.Component<{},{}> {
  private childComponent: any;

  render(){
    <View>
      <ChildComponent ref={ref => this.childComponent = ref as any}>
    </View>
  }
}

Here, the method "childMethod" is undefined when using the ref in the parent component. Without using connect, everything works fine.

like image 572
vbvx Avatar asked Jun 27 '18 12:06

vbvx


People also ask

Can useRef pass to child component?

The forwardRef hooks allows React users to pass refs to child components. The ref can be created and referenced with useRef or createRef and then passed in a parent component.

How do you pass parent ref to child component?

React forwardRef is a method that allows parent components pass down (i.e., “forward”) refs to their children. Using forwardRef in React gives the child component a reference to a DOM element created by its parent component. This then allows the child to read and modify that element anywhere it is being used.


1 Answers

Doing this is generally labelled as bad practice. Another option that is generally a much better approach is to do the following.

class Parent extends React.Component {

   state = {
       functionToCallInChild = null;
   }

   render() {
       return (
           <Child setCallable={callable => this.setState({functionToCallInChild: callable})}/>
       );
   }
}

class Child extends React.Component {

    componentDidMount() {
       this.props.setCallable(this.childFunction);
    }

    childFunction = () => console.log("It worked!");

    render() {
       return (</div>);
    }
}

You can see, once the child renders, the parent now has access to call the child's function.

like image 65
Francis Malloch Avatar answered Sep 30 '22 06:09

Francis Malloch