web-dev-qa-db-fra.com

Comment utiliser les boutons radio dans ReactJS?

Je suis nouveau sur ReactJS, désolé si cela sonne bien. J'ai un composant qui crée plusieurs lignes de table en fonction des données reçues.

Chaque cellule de la colonne a une case à cocher radio. Par conséquent, l'utilisateur peut sélectionner un site_name et un address parmi les lignes existantes. La sélection doit être indiquée dans le pied de page. Et c'est là que je suis coincé.

var SearchResult = React.createClass({
   render: function(){
       var resultRows = this.props.data.map(function(result){
           return (
               <tbody>
                    <tr>
                        <td><input type="radio" name="site_name" value={result.SITE_NAME}>{result.SITE_NAME}</input></td>
                        <td><input type="radio" name="address" value={result.ADDRESS}>{result.ADDRESS}</input></td>
                    </tr>
               </tbody>
           );
       });
       return (
           <table className="table">
               <thead>
                   <tr>
                       <th>Name</th>
                       <th>Address</th>
                   </tr>
               </thead>
                {resultRows}
               <tfoot>
                   <tr>
                       <td>chosen site name ???? </td>
                       <td>chosen address ????? </td>
                   </tr>
               </tfoot>
           </table>
       );
   }
});

Dans jQuery, je pourrais faire quelque chose comme $("input[name=site_name]:checked").val() pour obtenir la sélection d'un type de case à cocher radio et l'insérer dans la première cellule de pied de page.

Mais sûrement il doit y avoir un moyen Reactjs, qui me manque totalement? Merci beaucoup

164
Houman

Toute modification du rendu doit être modifiée via les paramètres state ou props ( react doc ).

Donc ici, j’enregistre l’événement de l’entrée, puis modifie la state, ce qui déclenchera ensuite l’affichage du rendu sur le pied de page.

var SearchResult = React.createClass({
  getInitialState: function () {
    return {
      site: '',
      address: ''
    };
  },
  onSiteChanged: function (e) {
    this.setState({
      site: e.currentTarget.value
      });
  },

  onAddressChanged: function (e) {
    this.setState({
      address: e.currentTarget.value
      });
  },

  render: function(){
       var resultRows = this.props.data.map(function(result){
           return (
               <tbody>
                    <tr>
                        <td><input type="radio" name="site_name" 
                                   value={result.SITE_NAME} 
                                   checked={this.state.site === result.SITE_NAME} 
                                   onChange={this.onSiteChanged} />{result.SITE_NAME}</td>
                        <td><input type="radio" name="address" 
                                   value={result.ADDRESS}  
                                   checked={this.state.address === result.ADDRESS} 
                                   onChange={this.onAddressChanged} />{result.ADDRESS}</td>
                    </tr>
               </tbody>
           );
       }, this);
       return (
           <table className="table">
               <thead>
                   <tr>
                       <th>Name</th>
                       <th>Address</th>
                   </tr>
               </thead>
                {resultRows}
               <tfoot>
                   <tr>
                       <td>chosen site name {this.state.site} </td>
                       <td>chosen address {this.state.address} </td>
                   </tr>
               </tfoot>
           </table>
       );
  }
});

jsbin

174
ChinKang

Voici un moyen simple d'implémenter des boutons radio dans react js.

class App extends React.Component {
  
  setGender(event) {
    console.log(event.target.value);
  }
  
  render() {
    return ( 
      <div onChange={this.setGender.bind(this)}>
        <input type="radio" value="MALE" name="gender"/> Male
        <input type="radio" value="FEMALE" name="gender"/> Female
      </div>
     )
  }
}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

édité

Vous pouvez utiliser la fonction flèche au lieu de la liaison. Remplacez le code ci-dessus par

<div onChange={event => this.setGender(event)}>

Pour une valeur par défaut, utilisez defaultChecked, comme ceci

<input type="radio" value="MALE" defaultChecked name="gender"/> Male
85

Transformez le composant radio en composant muet et transmettez les accessoires du parent.

import React from "react";

const Radiocomponent = ({ value, setGender }) => ( 
  <div onChange={setGender.bind(this)}>
    <input type="radio" value="MALE" name="gender" defaultChecked={value ==="MALE"} /> Male
    <input type="radio" value="FEMALE" name="gender" defaultChecked={value ==="FEMALE"}/> Female
  </div>
);

export default Radiocomponent;
16
Khalid Azam

Basé sur ce que les documents de React disent :

Gestion de plusieurs entrées. Lorsque vous devez gérer plusieurs éléments d'entrée contrôlés, vous pouvez ajouter un attribut name à chaque élément et laisser la fonction de gestionnaire choisir ce qu'elle doit faire. basé sur la valeur de event.target.name.

Par exemple:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  handleChange = e => {
    const { name, value } = e.target;

    this.setState({
      [name]: value
    });
  };

  render() {
    return (
      <div className="radio-buttons">
        Windows
        <input
          id="windows"
          value="windows"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
        Mac
        <input
          id="mac"
          value="mac"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
        Linux
        <input
          id="linux"
          value="linux"
          name="platform"
          type="radio"
          onChange={this.handleChange}
        />
      </div>
    );
  }
}

Lien vers l'exemple: https://codesandbox.io/s/6l6v9p0qkr

Au début, aucun des boutons radio n'est sélectionné, donc this.state est un objet vide, mais chaque fois que le bouton radio est sélectionné, this.state obtient une nouvelle propriété avec le nom de l'entrée et sa valeur. Il est alors facile de vérifier si l’utilisateur a sélectionné un bouton radio tel que:

const isSelected = this.state.platform ? true : false;

EDIT:

Avec la version 16.7-alpha de React il est une proposition pour quelque chose appelé hooks qui vous permettra de faire ce genre de choses plus facilement:

Dans l'exemple ci-dessous, il existe deux groupes de boutons radio dans un composant fonctionnel. Pourtant, ils ont des entrées contrôlées:

function App() {
  const [platformValue, plaftormInputProps] = useRadioButtons("platform");
  const [genderValue, genderInputProps] = useRadioButtons("gender");
  return (
    <div>
      <form>
        <fieldset>
          Windows
          <input
            value="windows"
            checked={platformValue === "windows"}
            {...plaftormInputProps}
          />
          Mac
          <input
            value="mac"
            checked={platformValue === "mac"}
            {...plaftormInputProps}
          />
          Linux
          <input
            value="linux"
            checked={platformValue === "linux"}
            {...plaftormInputProps}
          />
        </fieldset>
        <fieldset>
          Male
          <input
            value="male"
            checked={genderValue === "male"}
            {...genderInputProps}
          />
          Female
          <input
            value="female"
            checked={genderValue === "female"}
            {...genderInputProps}
          />
        </fieldset>
      </form>
    </div>
  );
}

function useRadioButtons(name) {
  const [value, setState] = useState(null);

  const handleChange = e => {
    setState(e.target.value);
  };

  const inputProps = {
    name,
    type: "radio",
    onChange: handleChange
  };

  return [value, inputProps];
}

Exemple de travail: https://codesandbox.io/s/6l6v9p0qkr

16
Tomasz Mularczyk

Juste une idée ici: quand il s’agit d’entrées radio dans React, je les ai toutes rendues d’une manière différente de celle mentionnée dans les réponses précédentes.

Si cela peut aider tous ceux qui ont besoin de générer beaucoup de boutons radio:

import React from "react"
import ReactDOM from "react-dom"

// This Component should obviously be a class if you want it to work ;)

const RadioInputs = (props) => {
  /*
    [[Label, associated value], ...]
  */
  
  const inputs = [["Male", "M"], ["Female", "F"], ["Other", "O"]]
  
  return (
    <div>
      {
        inputs.map(([text, value], i) => (
          <div key={ i }>
            <input type="radio"
              checked={ this.state.gender === value } 
              onChange={ /* You'll need an event function here */ } 
              value={ value } /> 
            { text }
          </div>
        ))
      }
    </div>
  )
}

ReactDOM.render(
  <RadioInputs />,
  document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
7
Arnaud

Le fait de cliquer sur un bouton radio devrait déclencher un événement qui:

  1. appelle setState, si vous voulez seulement que la connaissance de la sélection soit locale, ou
  2. appelle un rappel passé d'en haut self.props.selectionChanged(...)

Dans le premier cas, le changement d’état déclenchera un rendu et vous pourrez le faire.
<td>chosen site name {this.state.chosenSiteName} </td>

dans le second cas, la source du rappel va mettre à jour les éléments pour s'assurer que votre instance SearchResult aura choisi ChoisisSite et choisitAdresse dans ses accessoires.

2
z5h

Pour poursuivre sur la réponse de ChinKang, j’ai une approche plus sereine et une es6 pour les personnes intéressées:

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

    this.state = {
      selectedRadio: 'public'
    };
  }

  handleRadioChange = (event) => {
    this.setState({
      selectedRadio: event.currentTarget.value
    })
  };

  render() {
    return (
      <div className="radio-row">
        <div className="input-row">
          <input
            type="radio"
            name="public"
            value="public"
            checked={this.state.selectedRadio === 'public'}
            onChange={this.handleRadioChange}
          />
          <label htmlFor="public">Public</label>
        </div>
        <div className="input-row">
          <input
            type="radio"
            name="private"
            value="private"
            checked={this.state.selectedRadio === 'private'}
            onChange={this.handleRadioChange}
          />
          <label htmlFor="private">Private</label>
        </div>
      </div>
    )
  }
}

sauf que celui-ci aurait une valeur cochée par défaut.

1
Tony Tai Nguyen

Je me suis aussi trompé à la radio, à la mise en œuvre de cases à cocher. Ce dont nous avons besoin, c’est d’écouter changer d’événement de la radio, puis de définir l’état. J'ai fait un petit exemple de sélection du sexe.

/*
 * A simple React component
 */
class App extends React.Component {
  constructor(params) {
     super(params) 
     // initial gender state set from props
     this.state = {
       gender: this.props.gender
     }
     this.setGender = this.setGender.bind(this)
  }
  
  setGender(e) {
    this.setState({
      gender: e.target.value
    })
  }
  
  render() {
    const {gender} = this.state
    return  <div>
        Gender:
        <div>
          <input type="radio" checked={gender == "male"} 
onClick={this.setGender} value="male" /> Male
          <input type="radio" checked={gender == "female"} 
onClick={this.setGender} value="female"  /> Female
        </div>
        { "Select Gender: " } {gender}
      </div>;
  }
}

/*
 * Render the above component into the div#app
 */
ReactDOM.render(<App gender="male" />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
1
rab
import React, { Component } from "react";

class RadionButtons extends Component {
  constructor(props) {
    super(props);

    this.state = {
      // gender : "" , // use this one if you don't wanna any default value for gender
      gender: "male" // we are using this state to store the value of the radio button and also use to display the active radio button
    };

    this.handleRadioChange = this.handleRadioChange.bind(this);  // we require access to the state of component so we have to bind our function 
  }

  // this function is called whenever you change the radion button 
  handleRadioChange(event) {
      // set the new value of checked radion button to state using setState function which is async funtion
    this.setState({
      gender: event.target.value
    });
  }


  render() {
    return (
      <div>
        <div check>
          <input
            type="radio"
            value="male" // this is te value which will be picked up after radio button change
            checked={this.state.gender === "male"} // when this is true it show the male radio button in checked 
            onChange={this.handleRadioChange} // whenever it changes from checked to uncheck or via-versa it goes to the handleRadioChange function
          />
          <span
           style={{ marginLeft: "5px" }} // inline style in reactjs 
          >Male</span>
        </div>
        <div check>
          <input
            type="radio"
            value="female"
            checked={this.state.gender === "female"}
            onChange={this.handleRadioChange}
          />
          <span style={{ marginLeft: "5px" }}>Female</span>
        </div>
      </div>
    );
  }
}
export default RadionButtons;
1
ABHIJEET KHIRE