React-i18next: How to ref the child component after setting innnerRef inside withNamespaces

Created on 1 Nov 2018  路  14Comments  路  Source: i18next/react-i18next

I am using "react-i18next": "^8.3.5" and replaces all the
translate(withRef: true) to
withNamespaces(withRef: true, innnerRef: React.createRef)
Can anyone give some example on how to use the ref in parent component?
For example,
ChildComponent {
}
export default withNamespaces("", {
withRef: true,
innnerRef: React.createRef
})(ChildComponent);

ParentComponent{
dealWithChildComponent(){
const child =
this.refs.???.getWrappedInstance....
}
}

BTW, i could not visit the link of https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509, if it has an example, pls paste it here, thank you very much.

question

All 14 comments

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

function Parent(props) {
  return (
    <div>
      My input: <CustomTextInput inputRef={props.inputRef} />
    </div>
  );
}

class Grandparent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  render() {
    return (
      <Parent inputRef={this.inputElement} />
    );
  }
}

is the sample there -> just use innerRef instead of inputRef

@jamuhl, Thank you very much for the answer, i tried your way, i could get the this.inputElement.current, but the this.inputElement.current.WrappedInstance reports undefined error.
If i do not use the "withNamespaces", the function works well.
So i think i used the innerRef wrongly somewhere, here is my code prototype, can you help to tell me what's wrong of my code?

//Define Child component below
@connect(
  state => state.order,
  dispatch => bindActionCreators({ ...orderActions }, dispatch),
  null,
  { withRef: true }
)
class Child extends React.Component {
  render() {
    return (
      <div ref={this.props.innerRef} />
    );
  }
}
export default withNamespaces("", {
 withRef: true,
  innerRef: React.createRef()
})(Child);

//Define Parent component below
class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  onClick(){
      this.inputElement.current.WrappedInstance.someFunction();  ======> Error: WrappedInstance is Undefined
  }
  render() {
    return (
      <Child innerRef={this.inputElement} />
    );
  }
}

So innerRef is a required property to ref the child component in i18n? And how to get the WrappedInstance pls? Thanks for the help.

there is no longer a getWrappedInstance() function the function you pass to innerRef gives you that already

@jamuhl Is the ways i used innerRef correct?
Even if i do not use the getWrappedInstance, this.inputElement.current.someFunction() is also undefined. How to get the functions in Child component pls?

with innerRef you get set the ref prop on the wrappedElement

=> you forward a ref to a JSX node inside your component -> so you will need to use some different prop than innerRef to get that passed down inside your component (instead of set ref on your Component)

@jamuhl Not sure if i could totally understand. I change the code like below:

//Define Child component below
@connect(
  state => state.order,
  dispatch => bindActionCreators({ ...orderActions }, dispatch),
  null,
  { withRef: true }
)
class Child extends React.Component {
  render() {
    return (
      <div ref={this.props.myRef} />
    );
  }
}
export default withNamespaces("", {
 withRef: true,
  innerRef: React.createRef()
})(Child);

//Define Parent component below
class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  onClick(){
      this.inputElement.current.someFunctions  ======> Error: someFunctions is Undefined
  }
  render() {
    return (
      <Child myRef={this.inputElement} />
    );
  }
}

The current progress is this.inputElement.current returns the div DOM node, but what i want is the instance, and call the function in this instance.

Google is your friend...all you need to know is here: https://blog.logrocket.com/how-to-use-react-createref-ea014ad09dba

=> If needed you also can just use a callback ref might be simpler in this case.

@amycuicui I had the same problem.
Your questions and @jamuhl answers have guided me to proper solution.
Try this code:

class Child extends React.Component {

  methodAccessibleInParent() {
   console.log("I'm child!!!!!!");
  }  

  render() {
    return <span>Child component</span>;
  }
}

export default withNamespaces("", {
  innerRef: (ref} => {
    // Here *ref* is your child component instance with myRef function passed in props
     ref.props.myRef(ref);
})(Child);

class Parent extends React.Component {
 setMyRef = (ref) => console.log( "YEAH! i Have child component here!!!", ref.methodAccessibleInParent(), ref)
  render() {
   return(<Child myRef={this.setMyRef} />)
  }

}

Hope this helps.
Regards :)

@supersnager Thank you very much, it is helpful!

closing this ... if still unclear feel free to reopen.

If you like this module don鈥檛 forget to star this repo. Make a tweet, share the word or have a look at our https://locize.com to support the devs of this project -> there are many ways to help this project :pray:

imo you should provide a working example using withNamespaces and createRef

@EstebanBP currently working on the next upcoming versions...so why not letting the community do so...

@jamuhl It would be to nice see what @supersnager example would be using createRef instead of arrow function. I just cant make it work

Hello, my solution was:

class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.wrappedComponent = React.createRef()
  }

  _showChildInfo() {
     // Get Child Component 
    // this.wrappedComponent.current.state = { foo: 'bar }
    console.log(this.wrappedComponent.current)
  }

  render() {
    return (
      <Child refChild={this.wrappedComponent} />
    );
  }
}


class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      foo: 'bar'
    }
  }
  render() {
    return (
      <div>
        Child component
      </div>
    );
  }
}
export default withNamespaces({ innerRef: ref => { ref.props.refChild.current = ref } })(Child)

I'm using: "react-i18next": "^9.0.2"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ChCosmin picture ChCosmin  路  4Comments

ok2ju picture ok2ju  路  3Comments

martinlaregina picture martinlaregina  路  3Comments

a-barbieri picture a-barbieri  路  4Comments

pwiszowaty0 picture pwiszowaty0  路  4Comments