【问题标题】:How to use radio buttons in ReactJS?如何在 ReactJS 中使用单选按钮?
【发布时间】:2021-04-22 15:21:12
【问题描述】:

我是 ReactJS 的新手,如果这听起来不对劲,我很抱歉。我有一个组件可以根据接收到的数据创建多个表行。

列中的每个单元格都有一个单选复选框。因此,用户可以从现有行中选择一个site_name 和一个address。选择应显示在页脚中。这就是我卡住的地方。

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

在 jQuery 中,我可以执行 $("input[name=site_name]:checked").val() 之类的操作来选择一个单选复选框类型并将其插入到第一个页脚单元格中。

但肯定有一个 Reactjs 方式,我完全错过了?非常感谢

【问题讨论】:

  • input 元素没有内容。所以&lt;input&gt;content&lt;/input&gt; 没有意义并且无效。你可能想要&lt;label&gt;&lt;input /&gt;content&lt;/label&gt;
  • 单选按钮不是必须具有相同的名称和不同的值才能工作吗?

标签: html reactjs


【解决方案1】:

对渲染的任何更改都应通过stateprops (react doc) 进行更改。

所以在这里我注册了输入的事件,然后更改state,这将触发渲染显示在页脚上。

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

【讨论】:

  • 这非常有用。谢谢。我不明白的是}, this); 就在&lt;/tbody&gt; 下方。它是什么,它有什么作用?我注意到没有代码崩溃。
  • this 是传递给map function 的上下文。这是@FakeRainBrigand 的编辑,很好!没有它,您的地图函数中的this 将引用window,它不知道state 是关于什么的
  • 如果您使用 ES6 箭头而不是常规函数,则不需要此 this 技巧。例如:var resultRows = this.props.data.map((result) =&gt; { ... }); 我只提到它是因为 React-ers 通常已经在使用某种形式的转译(对于 JSX),所以 ES6 通常很容易获得。
  • 使用两个函数来获取单选按钮的值显得模棱两可且不必要。你可以只定义一个函数,也许是onInputChange (e) {this.setState({ [e.target.name]: e.target.value }); }
【解决方案2】:
import React from 'react';
import './style.css';

export default function App() {
  const [currentRadioValue, setCurrentValue] = React.useState('on');
  const handleRadioChange = value => {
    setCurrentValue(value);
  };
  return (
    <div>
      <>
        <div>
          <input
            name="radio-item-1"
            value="on"
            type="radio"
            onChange={e => setCurrentValue(e.target.value)}
            defaultChecked={currentRadioValue === 'on'}
          />
          <label htmlFor="radio-item-1">Radio Item 1</label>
          {currentRadioValue === 'on' && <div>one</div>}
        </div>
        <div>
          <input
            name="radio-item-1"
            value="off"
            type="radio"
            onChange={e => setCurrentValue(e.target.value)}
            defaultChecked={currentRadioValue === 'off'}
          />
          <label htmlFor="radio-item-2">Radio Item 2</label>
          {currentRadioValue === 'off' && <div>two</div>}
        </div>
      </>
    </div>
  );
}

工作示例:https://stackblitz.com/edit/react-ovnv2b

【讨论】:

  • 请对您的回答进行详细的解释,以便下一个用户更好地理解您的回答。此外,请提供链接内容的基本介绍,以防将来停止工作。
【解决方案3】:

这是我用过的。希望这会有所帮助。
先定义变量。

const [variableName, setVariableName] = useState("");

然后,我们将需要实际的单选按钮。

<input
   type="radio"
   name="variableName"
   value="variableToCheck"
   onChange={(e) =>
   setVariableName("variableToCheck")
   }
   checked={variableName === "variableToCheck"}
/>

【讨论】:

    【解决方案4】:

    @Tomasz Mularczyk 在他的回答中提到了 react 钩子,但我想我会提出一个我最近使用的解决方案,它只使用了 useState 钩子。

    function Radio() {
      const [currentRadioValue, setCurrentRadioValue] = useState()
    
      const handleRadioChange = (e) => {
        setCurrentValue(e.target.value);
      };
    
      return ( 
        <>
          <div>
            <input
              id="radio-item-1"
              name="radio-item-1"
              type="radio"
              value="radio-1"
              onChange={handleRadioChange}
              checked={currentRadioValue === 'radio-1'}
            />
            <label htmlFor="radio-item-1">Radio Item 1</label>
          </div>
          <div>
            <input
              id="radio-item-2"
              name="radio-item-2"
              type="radio"
              value="radio-2"
              onChange={handleRadioChange}
              checked={currentRadioValue === 'radio-2'}
            />
            <label htmlFor="radio-item-2">
              Radio Item 1
            </label>
          </div>
        </>
      );
    }
    

    【讨论】:

      【解决方案5】:

      将 radio 组件设为哑组件,并从 parent 传递 props。

      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;
      

      很容易测试,因为它是一个哑组件(纯函数)。

      【讨论】:

      • 应该使用“checked”。我很确定这是对“defaultChecked”的错误使用...
      【解决方案6】:

      Bootstrap 伙计们,我们是这样做的:

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

      【讨论】:

        【解决方案7】:
        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;
        

        【讨论】:

        • 你的代码有效,但你也应该解释一下
        • 注意:不要在 onChange 处理程序中使用 preventDefault,因为它会阻止将 checked 设置为DOM 组件
        【解决方案8】:

        基于React Docs say

        处理多个输入。 当需要处理多个受控输入元素时,可以给每个元素添加一个name属性,让handler函数根据event.target.name的值来选择做什么。

        例如:

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

        示例链接:https://codesandbox.io/s/6l6v9p0qkr

        首先,没有选择单选按钮,因此@ 987654326是一个空对象,但只要选择单选按钮this.state获取输入的名称及其值。然后检查用户是否选择了任何单选按钮,例如:

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

        编辑:

        使用 React 的 16.7-alpha 版本,is a proposal 有一个叫做 hooks 的东西,它可以让你更轻松地做这种事情:

        在下面的示例中,一个功能组件中有两组单选按钮。尽管如此,他们还是有控制输入:

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

        工作示例:https://codesandbox.io/s/6l6v9p0qkr

        【讨论】:

          【解决方案9】:

          这是在 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>

          已编辑

          您可以使用箭头函数代替绑定。将上面的代码替换为

          &lt;div onChange={event =&gt; this.setGender(event)}&gt;

          默认值使用defaultChecked,像这样

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

          【讨论】:

          • 相信.bind(this)每次都会创建一个新函数。这意味着当 react 检查虚拟 DOM 中是否有任何变化时,这个组件总是不同的,并且总是需要重新渲染。
          • 每次渲染的新函数只有在将该函数作为道具传递给子组件时才会成为问题。在这种情况下,接收道具的子组件可能会不必要地渲染。父组件会很好。
          • 对我来说,这仅适用于单击每个具有相同名称的收音机。例如,我有两个具有相同 name 属性的收音机。它们都包装在一个具有onChange 处理程序的 div 中,如本答案中所述。我单击第一个收音机,触发了一个事件。我单击第二个收音机,触发了一个事件。但是,第三次及以后,不会触发任何事件。为什么?
          • @Saahithyan 我在所有收音机上都附加了相同的名称属性。结果我需要将一个 onClick 处理程序放到无线电输入而不是一个 onChange 处理程序。成功了。
          • 我同意@Sqrler 的观点——使用 onChange,对于 div 下包含的每个单选按钮,句柄只会触发一次。使用 onClick,它可以多次工作。不知道为什么这与你的 sn-p...
          【解决方案10】:

          为了在 ChinKang 的回答基础上再接再厉,对于那些感兴趣的人,我有一个更干的方法和 es6:

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

          除了这个会有一个默认的检查值。

          【讨论】:

            【解决方案11】:

            这里只是一个想法:当涉及到 React 中的无线电输入时,我通常以之前答案中提到的不同方式呈现所有这些。

            如果这可以帮助需要渲染大量单选按钮的人:

            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>

            【讨论】:

            • 这很棒。非常干燥,让事情变得美好。我会为每个选项使用一个对象,但我想这是一个偏好问题。
            • @nbkhope 如果我必须重写它,我也会使用 object 来代替! :)
            • 检查这一行:checked={ this.state.gender === value }。功能组件没有this
            • Intead of a div in: &lt;div key={ i }&gt; 我会设置一个标签。
            【解决方案12】:

            我也对收音机、复选框的实现感到困惑。我们需要的是,监听收音机的变化事件,然后设置状态。我做了一个性别选择的小例子。

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

            【讨论】:

              【解决方案13】:

              单击单选按钮应触发以下事件:

              1. 调用setState,如果你只希望选择知识是本地的,或者
              2. 调用从上面传入的回调self.props.selectionChanged(...)

              在第一种情况下,状态的改变会触发重新渲染,你可以这样做
              &lt;td&gt;chosen site name {this.state.chosenSiteName} &lt;/td&gt;

              在第二种情况下,回调的源将更新内容以确保您的 SearchResult 实例将在其 props 中设置 selectedSiteName 和 selectedAddress。

              【讨论】:

                猜你喜欢
                • 2016-04-05
                • 2019-04-13
                • 2021-09-21
                • 2018-10-24
                • 2021-09-19
                • 1970-01-01
                • 2014-10-14
                • 1970-01-01
                相关资源
                最近更新 更多