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

javascript - React Checkbox Controlled Component - Stack Overflow

programmeradmin4浏览0评论

This is driving me crazy. I have no problem with select drop downs and text fields, but for some reason, I cannot get checkboxes working in a controlled fashion. That it is I want them to 'toggle' and listen to this event in a parent ponent.

I understand there is a 'checked' property for inputs of type checkbox. Selecting a checkbox gives it a value of 'on'. I take this 'on' value and convert it to true or false, and update the ponent accordingly.

For some reason, I cannot get this to work, either it is always selected, or it is never selected (if I switch the boolean switch).

export class ControlledCheckbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      select: false,
    };
  }

  render() {
    console.info("this.state.select - " + this.state.select);

    let sel = false;

    if (this.state.select !== "on") {
      sel = true;
    } else {
      sel = false;
    }

    return (
      <div>
        <input
          type="checkbox"
          checked={sel}
          onChange={this.handleChangeCheckbox}
        />
      </div>
    );
  }

  handleChangeCheckbox = (e) => {
    console.info("here e.currentTarget.value " + e.currentTarget.value);

    this.setState({
      select: e.currentTarget.value,
    });
    //call passed through callback here
  };
}

This is driving me crazy. I have no problem with select drop downs and text fields, but for some reason, I cannot get checkboxes working in a controlled fashion. That it is I want them to 'toggle' and listen to this event in a parent ponent.

I understand there is a 'checked' property for inputs of type checkbox. Selecting a checkbox gives it a value of 'on'. I take this 'on' value and convert it to true or false, and update the ponent accordingly.

For some reason, I cannot get this to work, either it is always selected, or it is never selected (if I switch the boolean switch).

export class ControlledCheckbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      select: false,
    };
  }

  render() {
    console.info("this.state.select - " + this.state.select);

    let sel = false;

    if (this.state.select !== "on") {
      sel = true;
    } else {
      sel = false;
    }

    return (
      <div>
        <input
          type="checkbox"
          checked={sel}
          onChange={this.handleChangeCheckbox}
        />
      </div>
    );
  }

  handleChangeCheckbox = (e) => {
    console.info("here e.currentTarget.value " + e.currentTarget.value);

    this.setState({
      select: e.currentTarget.value,
    });
    //call passed through callback here
  };
}
Share Improve this question edited May 2, 2020 at 13:07 Dennis Vash 54k12 gold badges117 silver badges132 bronze badges asked May 2, 2020 at 12:52 Oliver WatkinsOliver Watkins 13.6k39 gold badges134 silver badges252 bronze badges 1
  • codesandbox.io/s/objective-tereshkova-tcdq9?file=/src/App.js – acbay Commented May 2, 2020 at 13:06
Add a ment  | 

2 Answers 2

Reset to default 5

value serves a different purpose for checkbox inputs and you should not use it to define your state's value. You need to take a look at the e.currentTarget.checked instead.

export class ControlledCheckbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      select: false,
    }
  }

  handleChangeCheckbox = e => {
    this.setState({
      select: e.currentTarget.checked // <--
    })
  }

  render() {
    return (
      <div>
        <input type="checkbox"
          checked={this.state.select}
          onChange={this.handleChangeCheckbox} />
      </div>
    );
  }
}

If you are working with multiple inputs (not only checkboxes) you can follow the approach suggested by react docs, where you can cover multiple input types with only one setState. Keep in mind to define a name in this case, so you can separate your inputs:

handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

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

render() {
    return (
      <div>
        <input type="checkbox"
          name="hasValue"
          checked={this.state.select}
          onChange={this.handleChangeCheckbox} />
      </div>
    );
}

Your question is about controlled inputs, however your checkbox isn't controlled yet. You rely on the value stored inside checkbox, not inside the state.

this.setState({
   select: e.currentTarget.value, // here
});

Use a value that es from the state instead.

this.setState((prevState) => ({
   select: !prevState.select,
}));

Note: You can remove the conditions from the render, they are redundant.

发布评论

评论列表(0)

  1. 暂无评论