2 votes

Transformer plusieurs entrées React onChange en un seul tableau

J'ai un état qui est un tableau dans le composant A. J'ai ensuite un composant B (dont les props sont l'état du composant A) dans lequel un certain nombre d'entrées (type texte) sont générées en fonction de l'état de A. Disons 3, alors j'ai 3 saisies de type texte, elles sont enveloppées dans un composant différent et dans un div. Je me demande si je peux d'une certaine manière onChange obtenir une valeur des trois et l'ajouter au tableau dans le composant A? L'ordre n'est pas important. Peut-être qu'il y a quelque chose comme obtenir les enfants de ce conteneur div et ensuite mapper toutes leurs valeurs onChange dans un tableau et définir l'état? Quelque chose comme ça

Modifier:

Alors j'ai écrit ceci, je vois que les noms sont corrects, mais je reçois cette erreur: "Attention: cet événement synthétique est réutilisé pour des raisons de performance. Si vous voyez ceci, vous accédez à la propriété cible sur .... bla bla bla". Pourquoi ai-je le sentiment que mon setState n'est pas pur. D'accord, je fais une pause...

  onMultipleChange(e) {
        console.log(e.target.name);
        this.setState((prevState, props) => {
            let publicKeys = {...prevState.publicKeys, [e.target.name]: e.target.value};
            return {...prevState, publicKeys}
        }, console.log(this.state));
    }

Définir les refs de cette manière dynamiquement:

refSetter = (ix) => (ref) => { this._refs[ix] = ref; };

2voto

lux Points 1949

Avertissement : Il s'agit d'une approche assez naïve, et cela semble évidemment bricolé, mais cela fonctionne néanmoins, et c'est légal. Je suis sûr qu'il existe une meilleure approche qui ne dépend pas des refs.

Exemple : https://codesandbox.io/s/002o3275jl

Composant A

class ComponentA extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      vals: []
    }
    this._refs = {};
  }

  onChange = () => {
    this.setState({
      vals: Object
        .keys(this._refs)
        .map(key => 
          this._refs[key] && 
          this._refs[key].value
        )
     });
  }

  render() {
    return (

        Toutes les valeurs : {this.state.vals.join(', ')}
         this._refs['b'] = ref} onChange={this.onChange} />
         this._refs['c'] = ref} onChange={this.onChange} />
         this._refs['d'] = ref} onChange={this.onChange} />

    )
  }
}

Composants enfants

const ComponentB = ({_ref, onChange}) => (

);

const ComponentC = ({ _ref,  onChange }) => (

);

const ComponentD = ({ _ref,  onChange }) => (

);

1voto

SrThompson Points 2150

J'ai construit sur la réponse de @lux (ce que je veux dire, c'est que j'ai littéralement pris son exemple et j'ai bidouillé avec) et j'ai trouvé une alternative qui ne nécessite pas de refs.

Récemment, j'ai appris que l'événement synthétique de React (qui est réutilisé à chaque fois) peut être persisté, ce qui signifie qu'il est retiré de la file d'événements, vous permettant de conserver la référence même si d'autres événements sont déclenchés. Voici ce à quoi je suis arrivé :

class ComponentA extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      vals: [
        {
          name: "ComponentB",
          value: ""
        },
        {
          name: "ComponentC",
          value: ""
        },
        {
          name: "ComponentD",
          value: ""
        },
      ]
    }
  }

  onChange = e => {
    e.preventDefault();
    e.persist();
    this.handleMultipleChanges(e);
  }

  handleMultipleChanges = e => {
    let currentInput = this.state.vals.find(val => val.name === e.target.name);
    currentInput.value = e.target.value;
    this.setState(prevState => ({
      ...prevState,
      vals: prevState.vals.map(val => val.name === currentInput.name ? currentInput : val)
    }));
  }

  render() {
    return (

        Tous les Vals : {this.state.vals.map(val => val.value).join(", ")}

    )
  }
}

const ComponentB = ({name, onChange}) => (

);

const ComponentC = ({name, onChange }) => (

);

const ComponentD = ({name, onChange }) => (

);

EDITION

Il s'agit d'une variante (assez basique) pour ajouter des saisies dynamiquement via une saisie de nombre, car c'était le cas d'utilisation de l'auteur du post :

class ComponentA extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputNumber: 0,
      vals: []
    }
  }

  onChange = e => {
    e.preventDefault();
    e.persist();
    this.handleMultipleChanges(e);
  }

  handleMultipleChanges = e => {
    let currentInput = this.state.vals.find(val => val.name === e.target.name);
    if (!currentInput) {
      currentInput = {
        name: e.target.name,
        value: e.target.value
      }
      this.setState({vals: this.state.vals.concat(currentInput)});
    } else {
      currentInput.value = e.target.value;
      this.setState(prevState => ({
        ...prevState,
        vals: prevState.vals.map(val => val.name === currentInput.name ? currentInput : val)
      }));
    }
  }

  createInputs = e => {
    const {inputNumber} = this.state;
    const vals = [];

    for (let i = 0; i
        AllVals : {this.state.vals.map(val => val.value).join(", ")}

         this.setState({inputNumber: e.target.value})} />
        Créer les saisies

        {this.state.vals.map(
          val => 
        )}

    )
  }
}

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