最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why are my radio buttons not toggling state in react? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to partially follow the react tutorial.

I'm at this point trying to create a ponent that has 2 input fields of type "radio". One is checked by default. I'm trying to mimic a behavior whereby if I click on the other radio button, the currently checked one will be turned off, and the one clicked will be turned on.

The thing is, after I click on the one not initially checked, they both turn off "forever".

I have debugged by code, and up to the call to setState everything works. The state is set as I want it to be set, but the buttons are not updating.

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

I am running this example with this codepen setup, which is what facebook provided:

Am I missing anything?

[EDIT] i updated the name of the inputs, and corrected the code. A different issue: Now the inputs NEVER change state. I debugged and the setState method is called with the proper state, however the buttons don't switch state. I put a breakpoint before the this.setState call, and the buttons looked ok then. They are being switched back to the initial state however after that point somewhere. I should probably try to put a DOM breakpoint of some kind....

The new code:

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

I'm trying to partially follow the react tutorial.

I'm at this point trying to create a ponent that has 2 input fields of type "radio". One is checked by default. I'm trying to mimic a behavior whereby if I click on the other radio button, the currently checked one will be turned off, and the one clicked will be turned on.

The thing is, after I click on the one not initially checked, they both turn off "forever".

I have debugged by code, and up to the call to setState everything works. The state is set as I want it to be set, but the buttons are not updating.

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

I am running this example with this codepen setup, which is what facebook provided: http://codepen.io/gaearon/pen/ZpvBNJ?editors=0010

Am I missing anything?

[EDIT] i updated the name of the inputs, and corrected the code. A different issue: Now the inputs NEVER change state. I debugged and the setState method is called with the proper state, however the buttons don't switch state. I put a breakpoint before the this.setState call, and the buttons looked ok then. They are being switched back to the initial state however after that point somewhere. I should probably try to put a DOM breakpoint of some kind....

The new code:

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>
    )
  }
}
Share Improve this question edited Mar 12, 2017 at 20:46 vlad-ardelean asked Mar 12, 2017 at 17:02 vlad-ardeleanvlad-ardelean 7,63215 gold badges86 silver badges128 bronze badges 2
  • 1 Radio inputs should have the same name attribute. – idbehold Commented Mar 12, 2017 at 17:06
  • @idbehold thanks, but that didn't do it. I updated my question. SOmething doesn't let the buttons change state at all now. – vlad-ardelean Commented Mar 12, 2017 at 17:29
Add a ment  | 

3 Answers 3

Reset to default 3

for the radio button the name attribute of the two input must match

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

change both names to "f" or some other string and try again.

See example below

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

I know that this question is too old, but it can help someone.

Try to remove the event.preventDefault() when you use this you prevent the main functionality of the radio button the toggle.

My problem, with ReactJS, was that I was defining the checked attribute of my radio buttons instead of the defaultChecked one !

发布评论

评论列表(0)

  1. 暂无评论