Làm thế nào để sử dụng các nút radio trong ReactJS?


203

Tôi chưa quen với ReactJS, xin lỗi nếu điều này nghe có vẻ tắt. Tôi có một thành phần tạo ra một số hàng bảng theo dữ liệu nhận được.

Mỗi ô trong cột có một hộp kiểm radio. Do đó người dùng có thể chọn một site_namevà một addresstừ các hàng hiện có. Các lựa chọn sẽ được hiển thị trong phần chân trang. Và đó là nơi tôi đang bị mắc kẹt.

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>
       );
   }
});

Trong jQuery tôi có thể làm một cái gì đó như $("input[name=site_name]:checked").val()để có được lựa chọn một loại hộp kiểm radio và chèn nó vào ô chân trang đầu tiên.

Nhưng chắc chắn phải có một cách Reactjs, mà tôi hoàn toàn thiếu? Cảm ơn nhiều


3
inputcác yếu tố không có nội dung. Vì vậy, <input>content</input>không có ý nghĩa và không hợp lệ. Bạn có thể muốn <label><input />content</label>.
Oriol

1
Các nút radio có phải có cùng tên với các giá trị khác nhau để hoạt động không?
pgee70

Câu trả lời:


209

Mọi thay đổi đối với kết xuất sẽ được thay đổi thông qua statehoặc props( phản ứng doc ).

Vì vậy, ở đây tôi đăng ký sự kiện của đầu vào, và sau đó thay đổi state, sau đó sẽ kích hoạt kết xuất để hiển thị trên chân trang.

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


3
Điều đó rất hữu ích. Cảm ơn. Những gì tôi không hiểu là bit }, this);ngay bên dưới </tbody>. Nó là gì và nó làm gì? Tôi nhận thấy mà không có mã bị lỗi.
Houman

3
Đây thislà bối cảnh được truyền cho mapchức năng . Đó là bản chỉnh sửa của @FakeRainBrigand, bắt tốt! Nếu không có nó this, chức năng bản đồ của bạn sẽ đề cập đến window, trong đó không biết ý nghĩa của statenó là gì
ChinKang

8
Đây thisBí quyết là không cần thiết nếu bạn sử dụng một ES6 mũi tên thay vì một hàm thông thường. Ví dụ: var resultRows = this.props.data.map((result) => { ... });Tôi chỉ đề cập đến nó bởi vì React-ers thường đã sử dụng một số hình thức dịch mã (đối với JSX), vì vậy ES6 thường nằm trong tầm tay dễ dàng.
Tom

1
Sử dụng hai chức năng để có được các giá trị của các nút radio có vẻ mơ hồ và không cần thiết. Bạn chỉ có thể xác định một chức năng, có lẽonInputChange (e) {this.setState({ [e.target.name]: e.target.value }); }
xplorer1

109

Đây là một cách đơn giản nhất để thực hiện các nút radio trong phản ứng 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>

Đã chỉnh sửa

Bạn có thể sử dụng chức năng mũi tên thay vì ràng buộc. Thay thế mã trên là

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

Để sử dụng giá trị mặc định defaultChecked, như thế này

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

6
Tôi tin rằng .bind(this)sẽ tạo ra một chức năng mới mỗi lần. Điều này có nghĩa là khi phản ứng kiểm tra xem liệu có gì thay đổi trong DOM ảo hay không, thành phần này sẽ luôn khác và luôn cần kết xuất lại.
WoodKitty

1
Chức năng mới trên mỗi kết xuất sẽ chỉ là một vấn đề nếu truyền chức năng này xuống dưới dạng đạo cụ cho một thành phần con. Trong trường hợp đó, thành phần con nhận đạo cụ có thể hiển thị không cần thiết. Thành phần cha mẹ sẽ ổn.
Đánh dấu McKelvy

5
Đối với tôi, điều này chỉ hoạt động một lần để nhấp vào mỗi đài có cùng tên. Ví dụ, tôi có hai đài phát thanh có cùng một chỗ dựa name. Cả hai đều được bọc trong một div có onChangexử lý như được mô tả trong câu trả lời này. Tôi bấm vào đài phát thanh đầu tiên, một sự kiện được kích hoạt. Tôi bấm vào đài phát thanh thứ hai, một sự kiện được kích hoạt. Lần thứ ba trở đi, tuy nhiên, không có sự kiện nào bị sa thải. Tại sao?
Squrler

4
@Saahithyan Tôi có thuộc tính cùng tên được gắn vào tất cả các bộ đàm. Hóa ra tôi cần đặt trình xử lý onClick vào đầu vào radio thay vì trình xử lý onChange. Điều đó đã lừa
Squrler

3
Tôi đồng ý với @Squrler - với onChange, tay cầm chỉ kích hoạt một lần cho mỗi nút radio được bao gồm trong div. Với onClick, nó hoạt động nhiều lần. Không chắc tại sao điều đó được so sánh với đoạn trích của bạn ...
JESii

25

Dựa trên những gì React Docs nói :

Xử lý nhiều đầu vào. Khi bạn cần xử lý nhiều yếu tố đầu vào được kiểm soát, bạn có thể thêm thuộc tính name cho từng thành phần và để chức năng xử lý chọn việc cần làm dựa trên giá trị của event.target.name.

Ví dụ:

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>
    );
  }
}

Liên kết đến ví dụ: https://codesandbox.io/s/6l6v9p0qkr

Lúc đầu, không có nút radio nào được chọn vì vậy this.statelà một đối tượng trống, nhưng bất cứ khi nào nút radio được chọn this.statesẽ có một thuộc tính mới với tên của đầu vào và giá trị của nó. Sau đó, nó dễ dàng kiểm tra xem người dùng có chọn bất kỳ nút radio nào không:

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

BIÊN TẬP:

Với phiên bản 16.7-alpha của React, có một đề xuất cho một thứ gọi là hookssẽ cho phép bạn thực hiện loại công cụ này dễ dàng hơn:

Trong ví dụ dưới đây, có hai nhóm nút radio trong một thành phần chức năng. Tuy nhiên, họ đã kiểm soát đầu vào:

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];
}

Ví dụ hoạt động: https://codesandbox.io/s/6l6v9p0qkr


20

Làm cho thành phần vô tuyến thành thành phần câm và truyền đạo cụ từ cha mẹ.

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;

2
thật dễ dàng để kiểm tra vì nó là thành phần kết xuất là một hàm thuần túy.
Khalid Azam

7

Chỉ là một ý tưởng ở đây: khi nói đến đầu vào radio trong React, tôi thường kết xuất tất cả chúng theo một cách khác đã được đề cập trong các câu trả lời trước.

Nếu điều này có thể giúp bất cứ ai cần kết xuất nhiều nút 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>


1
Điều đó thật tuyệt. Rất DRY và làm cho mọi thứ tốt đẹp. Tôi sẽ sử dụng một đối tượng cho mỗi tùy chọn, nhưng đó là vấn đề ưu tiên, tôi đoán vậy.
nbkhope

@nbkhope nếu tôi phải viết lại, tôi cũng sẽ sử dụng đối tượng! :)
Arnaud

Kiểm tra dòng này : checked={ this.state.gender === value }. Các thành phần chức năng không có this.
Áp-ra-ham

6
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
Mã của bạn hoạt động nhưng bạn cũng nên giải thích một chút
Rahul Sharma

Chú ý : không sử dụng preventDefault trong handler onChange bởi vì nó ngăn chặn thiết lập được kiểm tra để thành phần DOM
AlexNikonov

2

Nhấp vào nút radio sẽ kích hoạt một sự kiện:

  1. gọi setState, nếu bạn chỉ muốn kiến ​​thức lựa chọn là cục bộ, hoặc
  2. gọi lại một cuộc gọi lại đã được thông qua từ phía trên self.props.selectionChanged(...)

Trong trường hợp đầu tiên, thay đổi là trạng thái sẽ kích hoạt kết xuất lại và bạn có thể làm
<td>chosen site name {this.state.chosenSiteName} </td>

trong trường hợp thứ hai, nguồn của cuộc gọi lại sẽ cập nhật mọi thứ để đảm bảo rằng xuống dòng, đối tượng SearchResult của bạn sẽ chọnSiteName và chọnAddress được đặt trong đạo cụ của nó.


2

Để xây dựng dựa trên câu trả lời của ChinKang, tôi có cách tiếp cận khô khan hơn và trong es6 cho những ai quan tâm:

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>
    )
  }
}

ngoại trừ cái này sẽ có một giá trị được kiểm tra mặc định.


1

Tôi cũng đã nhầm lẫn trong đài phát thanh, hộp kiểm thực hiện. Những gì chúng ta cần là, nghe sự kiện thay đổi của đài phát thanh, và sau đó thiết lập trạng thái. Tôi đã làm một ví dụ nhỏ về lựa chọn giới tính.

/*
 * 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>


0

Bootstrap guys, chúng tôi làm như thế này:


export default function RadioButton({ onChange, option }) {
    const handleChange = event => {
        onChange(event.target.value)
    }

    return (
        <>
            <div className="custom-control custom-radio">
                <input
                    type="radio"
                    id={ option.option }
                    name="customRadio"
                    className="custom-control-input"
                    onChange={ handleChange }
                    value = { option.id }
                    />
                    <label
                        className="custom-control-label"
                        htmlFor={ option.option }
                        >
                        { option.option }
                    </label>
            </div>
        </>
    )
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.