82 votes

Comment accéder aux références d'un composant enfant dans le composant parent ?

Si j'ai quelque chose comme

<Parent>
  <Child1 />
  <Child2 />
  <Child3 />
</Parent>

Et je veux accéder à partir de Child2 où j'ai refs="child2refs" Comment puis-je faire ça ?

0 votes

Pouvez-vous poster votre code react ici ? this.props.children devrait toujours word dans ce cas...

0 votes

Pour accéder à l'enfant, nous pouvons ajouter une référence à celui-ci <Child2 ref="child2" /> et y accéder par this.refs.child. Cela ne fonctionnera pas sur un composant connecté( un composant qui est connecté à redux ou à d'autres plugins ). Nous devons utiliser getWrappedInstance() pour obtenir l'instance enveloppée et ensuite nous pouvons accéder à l'état, aux refs et aux méthodes de ce composant. Voici la vidéo qui l'explique - youtu.be/VpdKjocgCtA

1 votes

Il y a maintenant la possibilité de faire suivre les arbitrages : reactjs.org/docs/forwarding-refs.html

3voto

Monsingor Points 496

Si tout ce que vous avez est props.children :

const Parent = (p: {children: JSX.Element}) => {
    const childRef = useRef()

    return React.cloneElement(p.children, { ref: childRef })
}

<Parent>
  <SingleChild />
</Parent>

Notez qu'il échouera si votre enfant ne peut pas avoir un ref par exemple React.Fragment .

2voto

OZZIE Points 367

Je pense que ce guide l'explique assez bien https://github.com/yannickcr/eslint-plugin-react/issues/678

class Field extends Component {
  const { inputRef } = this.props;
  render() {
    return (
      <input type="text" ref={inputRef} />
    )
  }
}

class MyComponent extends Component {
  componentDidMount() {
    this.inputNode.focus();
  }

  render() {
    return (
      <div>
        Hello, <Field inputRef={node => this.inputNode = node} />
      </div>
    )
  }
}

2voto

Ryan Weiss Points 118

Voici comment je résous le problème pour les composants dynamiques :

Sur le parent, créez dynamiquement des références aux composants enfants, par exemple :

class Form extends Component {
    fieldRefs: [];

    // dynamically create the child references on mount/init
    componentWillMount = () => {
        this.fieldRefs = [];
        for(let f of this.props.children) {
            if (f && f.type.name == 'FormField') {
                f.ref = createRef();
                this.fieldRefs.push(f);
            }
        }
    }

    // used later to retrieve values of the dynamic children refs
    public getFields = () => {
        let data = {};

        for(let r of this.fieldRefs) {
            let f = r.ref.current;
            data[f.props.id] = f.field.current.value;
        }

        return data;
    }
}

Le composant enfant (c'est-à-dire <FormField />) met en œuvre sa propre référence de "champ", à laquelle il est fait référence à partir du parent :

class FormField extends Component {
    field = createRef();

    render() {
        return(
            <input ref={this.field} type={type} />
        );
    }
}

Ensuite, dans votre page principale, le composant "parent du parent", vous pouvez obtenir les valeurs des champs à partir de la référence avec :

class Page extends Component {
    form = createRef();

    onSubmit = () => {
        let fields = this.form.current.getFields();
    }

    render() {
        return (
            <Form ref={this.form}>
                <FormField id="email" type="email" autoComplete="email" label="E-mail" />
                <FormField id="password" type="password" autoComplete="password" label="Password" />

                <div class="button" onClick={this.onSubmit}>Submit</div>
            </Form>
        );
    }
}

Je l'ai mis en œuvre parce que je voulais encapsuler toutes les fonctionnalités de formulaire générique à partir d'un composant principal <Form />, et la seule façon de faire en sorte que le composant principal client/page définisse et mette en forme ses propres composants internes était d'utiliser des composants enfants (c'est-à-dire des éléments <FormField /> à l'intérieur du composant parent <Form />, qui se trouve à l'intérieur d'un autre composant <Page />).

Ainsi, alors que certains pourraient considérer cela comme un hack, c'est tout aussi bidon que les tentatives de React de bloquer le 'ref' réel de tout parent, ce qui est à mon avis une conception ridicule, quelle que soit la façon dont ils veulent le rationaliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X