为什么我的单选按钮没有响应状态?

时间:2017-03-12 17:03:00

标签: javascript reactjs

我正在尝试部分遵循反应教程。

我正在尝试创建一个具有“radio”类型的2个输入字段的组件。默认情况下会选中一个。我试图模仿一种行为,如果我点击另一个单选按钮,当前选中的一个将被关闭,单击的那个将被打开。

问题是,在我点击最初未检查的那个之后,它们都“永远”关闭。

我已经通过代码进行了调试,直到调用setState一切正常。状态设置为我想要设置,但按钮没有更新。

class App extends React.Component{
  constructor(props){
    super(props)
    this.state = this.createInitialState({celsiusChecked: true})
    this.handleRadioTicked = this.handleRadioTicked.bind(this)
  }

  createInitialState(additionalState={}){
    let state = {
      fahrenheitChecked: false,
      celsiusChecked: false
    }

    state = Object.assign(state, additionalState)

    return state
  }

  handleRadioTicked(event){
    event.preventDefault()

    let radioName = event.target.name
    let stateProperty

    if (radioName === 'c'){
      stateProperty = 'celsiusChecked'
    } else if (radioName === 'f'){
      stateProperty = 'fahrenheitChecked'
    } else {
      throw Exception("something bad happened...probably the input field names have changed")
    }

    let newState = this.createInitialState()
    newState[stateProperty]= true;

    // the newState is calculated OK. Checked for both buttons.
    // Also, initially, the buttons render properly
    this.setState(newState) 
  }

  render(){
    return (
      <div>
          <form>
            <fieldset>
              <input type="radio" name="f" value="fahrenheit" checked={this.state.fahrenheitChecked} onChange={this.handleRadioTicked}/>
              <label htmlFor="f">Fahrenheit</label>
              <input type="radio" name="c" value="celsius" checked={this.state.celsiusChecked} onChange={this.handleRadioTicked}/>
              <label htmlFor="c">Celsius</label>
            </fieldset>
        </form>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

我正在使用此代码集设置运行此示例,这是facebook提供的内容:http://codepen.io/gaearon/pen/ZpvBNJ?editors=0010

我错过了什么吗?

[编辑] 我更新了输入的名称,并更正了代码。另一个问题:现在输入永远不会改变状态。我调试了setState方法并调用了正确的状态,但是按钮没有切换状态。我在this.setState调用之前设置了断点,然后按钮看起来没问题。他们正在切换回初始状态但是在那之后的某个地方。我应该尝试设置某种DOM断点....

新代码:

class App extends React.Component{
  constructor(props){
    super(props)
    this.state = this.createInitialState({celsiusChecked: true})
    this.handleRadioTicked = this.handleRadioTicked.bind(this)

    this.setState = this.setState.bind(this)
  }

  createInitialState(additionalState={}){
    let state = {
      fahrenheitChecked: false,
      celsiusChecked: false
    }

    state = Object.assign(state, additionalState)

    return state
  }

  handleRadioTicked(event){
    event.preventDefault()

    let radioValue = event.target.value
    let stateProperty

    if (radioValue === 'celsius'){
      stateProperty = 'celsiusChecked'
    } else if (radioValue === 'fahrenheit'){
      stateProperty = 'fahrenheitChecked'
    } else {
      throw Exception("something bad happened...probably the input field names have changedx")
    }

    let newState = this.createInitialState()
    newState[stateProperty]= true;

    // Here the newState is succesfully created each time
    // ...still, the radio buttons don't "react" appropriately - pardon the pun
    this.setState(newState) 
  }

  render(){
    return (
      <div>
          <form>
            <fieldset>
              <input type="radio" name="scale" value="fahrenheit" checked={this.state.fahrenheitChecked} onChange={this.handleRadioTicked}/>
              <label htmlFor="f">Fahrenheit</label>
              <input type="radio" name="scale" value="celsius" checked={this.state.celsiusChecked} onChange={this.handleRadioTicked}/>
              <label htmlFor="c">Celsius</label>
            </fieldset>
        </form>
      </div>
    )
  }
}

3 个答案:

答案 0 :(得分:1)

对于单选按钮,两个输入的name属性必须匹配

<input type="radio" name="f" 

将两个名称更改为“f”或其他字符串,然后重试。

见下面的例子

  <input type="radio" name="gender" value="male" checked> Male<br>
  <input type="radio" name="gender" value="female"> Female<br>

答案 1 :(得分:1)

我知道这个问题太旧了,但是可以帮助别人。

尝试使用event.preventDefault()来移除它时,将阻止单选按钮的主要功能切换。

答案 2 :(得分:0)

ReactJS 的问题是我定义了单选按钮的 checked 属性而不是 defaultChecked 属性!