React JSX: การเลือก“ ถูกเลือก” ในตัวเลือก <select> ที่เลือก


402

ในส่วนประกอบ React สำหรับ<select>เมนูฉันต้องตั้งค่าแอselectedททริบิวในตัวเลือกที่สะท้อนถึงสถานะแอปพลิเคชัน

ในrender()ที่optionStateถูกส่งผ่านจากเจ้าของรัฐเพื่อองค์ประกอบ SortMenu ค่าตัวเลือกจะถูกส่งผ่านเป็นpropsจาก JSON

render: function() {
  var options = [],
      optionState = this.props.optionState;

  this.props.options.forEach(function(option) {
    var selected = (optionState === option.value) ? ' selected' : '';

    options.push(
      <option value={option.value}{selected}>{option.label}</option>
    );
  });

// pass {options} to the select menu jsx

อย่างไรก็ตามที่ก่อให้เกิดข้อผิดพลาดทางไวยากรณ์ในการรวบรวม JSX

การทำเช่นนี้เป็นการกำจัดข้อผิดพลาดทางไวยากรณ์ แต่เห็นได้ชัดว่าไม่ได้แก้ปัญหา:

var selected = (optionState === option.value) ? 'selected' : 'false';

<option value={option.value} selected={selected}>{option.label}</option>

ฉันก็ลองทำเช่นนี้:

var selected = (optionState === option.value) ? true : false;

<option value={option.value} {selected ? 'selected' : ''}>{option.label}</option>

มีวิธีแนะนำในการแก้ปัญหานี้หรือไม่?


การถอนคำถามออกจากชื่อ
ericgio

คำตอบ:


647

ตอบสนองอัตโนมัติเข้าใจบูลีนเพื่อจุดประสงค์นี้ดังนั้นคุณสามารถเขียนได้(หมายเหตุ: ไม่แนะนำ)

<option value={option.value} selected={optionsState == option.value}>{option.label}</option>

และมันจะแสดงผล 'เลือก' อย่างเหมาะสม

อย่างไรก็ตาม React ทำให้สิ่งนี้ง่ายยิ่งขึ้นสำหรับคุณ แทนที่จะกำหนดselectedแต่ละตัวเลือกคุณสามารถ (และควร) เขียนvalue={optionsState}บนแท็กเลือกเอง :

<select value={optionsState}>
  <option value="A">Apple</option>
  <option value="B">Banana</option>
  <option value="C">Cranberry</option>
</select>

สำหรับข้อมูลเพิ่มเติมให้ดูที่แท็กเลือกตอบกลับ


56
ด้วยเวอร์ชันปัจจุบันของ React (0.9) การตั้งค่าคุณสมบัติที่เลือกไว้บนตัวเลือกจะไม่ทำงานเลย ตั้งค่าคุณลักษณะในองค์ประกอบที่เลือกแทน
liammclennan

2
ฉันโหลดข้อมูลด้วย ajax.defaultValue ไม่ทำงานสำหรับฉัน ค่าใช้งานได้ แต่ฉันไม่สามารถเลือกรายการอื่นในรายการที่เลือกได้กำลังเปิดอยู่ แต่เมื่อฉันเลือกรายการใดรายการหนึ่งให้เลือกรายการค่าแนวคิดใด ๆ
user1924375

5
@ user1924375 คุณควรใช้เหตุการณ์ onChange onChange={this.handleSelect}และตั้งค่าสถานะสำหรับส่วนประกอบของคุณตัวอย่างเช่น: 'handleSelect: function () {this.setState ({value: event.target.value});} `สิ่งนี้จะแสดงองค์ประกอบที่คุณเลือกด้วย new รายการที่เลือก หวังว่ามันจะช่วยคุณ
funnydaredevil

1
แม้ว่าจะยังไม่ได้บันทึกไว้ แต่valueprop ของ a <select>สามารถเป็นอาร์เรย์ได้หากคุณmultiselectเปิดใช้งาน
tirdadc

4
แทนที่จะใช้defaultValueเพื่อเริ่มต้น
dewwwald

70

คุณสามารถทำสิ่งที่ตอบสนองเตือนคุณเมื่อคุณพยายามตั้งค่าคุณสมบัติ "เลือก" ของ<option>:

ใช้defaultValueหรือvalueอุปกรณ์ประกอบฉากใน<select>แทนของการตั้งค่าบนselected<option>

ดังนั้นคุณสามารถใช้options.valueในการdefaultValueเลือกของคุณ


9
หากฉันยังต้องการระบุตัวเลือกที่เลือกไว้ในปัจจุบันฉันจะทำสิ่งนี้ได้อย่างไร วิธีเดียวที่ฉันสามารถรักษาตัวเลือกที่เลือกไว้ (และรักษาสถานะของฟอร์มสำหรับการโพสต์ในอนาคต) โดยการตั้งค่า select = true ฉันได้ลองตั้งค่าเริ่มต้นมูลค่าและอุปกรณ์ประกอบฉากขององค์ประกอบที่เลือกแล้ว แต่นี่ไม่ได้แสดงผลในมุมมองโดยการตั้งค่าตัวเลือกที่ถูกต้องเพื่อเลือกในเมนูตัวเลือก คำแนะนำใด ๆ?
ไพพ์ไพพ์

4
ตัวอย่างอาจ?
shinzou

1
ไม่ทำงานสำหรับฉัน: <select className = "form-control" value = "Mois">
Kuartz

2
defaultValue ไม่สามารถใช้งานกับรุ่นใหม่ล่าสุด
Hos Mercury

18

ต่อไปนี้เป็นคำตอบที่สมบูรณ์ซึ่งรวมคำตอบที่ดีที่สุดและความคิดเห็นไว้ด้านล่าง (ซึ่งอาจช่วยให้ใครบางคนพยายามรวมเข้าด้วยกัน)

อัพเดตสำหรับ ES6 (2019) - การใช้ฟังก์ชั่นลูกศรและการทำลายวัตถุ

ในองค์ประกอบหลัก:

class ReactMain extends React.Component {

  constructor(props) {
    super(props);
    this.state = { fruit: props.item.fruit };
  }

  handleChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  }

  saveItem = () => {
    const item = {};
    item.fruit = this.state.fruit;
    // do more with item object as required (e.g. save to database)
  }

  render() {
    return (
      <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
    )
  }

}

ส่วนประกอบที่รวมอยู่ (ซึ่งขณะนี้เป็นฟังก์ชันไร้สัญชาติ):

export const ReactExample = ({ name, value, handleChange }) => (
  <select name={name} value={value} onChange={handleChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
  </select>
)

คำตอบก่อนหน้า (ใช้การผูก):

ในองค์ประกอบหลัก:

class ReactMain extends React.Component {

  constructor(props) {
    super(props);
    // bind once here, better than multiple times in render
    this.handleChange = this.handleChange.bind(this);
    this.state = { fruit: props.item.fruit };
  }

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

  saveItem() {
    const item = {};
    item.fruit = this.state.fruit;
    // do more with item object as required (e.g. save to database)
  }

  render() {
    return (
      <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
    )
  }

}

ส่วนประกอบที่รวมอยู่ (ซึ่งขณะนี้เป็นฟังก์ชันไร้สัญชาติ):

export const ReactExample = (props) => (
  <select name={props.name} value={props.value} onChange={props.handleChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
  </select>
)

องค์ประกอบหลักรักษาค่าที่เลือกสำหรับผลไม้ (ในสถานะ) ส่วนประกอบที่รวมจะแสดงองค์ประกอบที่เลือกและการอัปเดตจะถูกส่งกลับไปยังองค์ประกอบหลักเพื่ออัปเดตสถานะของมัน (ซึ่งจะวนกลับไปที่องค์ประกอบที่รวมไว้เพื่อเปลี่ยนค่าที่เลือก)

หมายเหตุการใช้ชื่อ prop ซึ่งช่วยให้คุณประกาศวิธีการ handleChange เดียวสำหรับเขตข้อมูลอื่น ๆ ในรูปแบบเดียวกันโดยไม่คำนึงถึงชนิดของพวกเขา


หมายเหตุบรรทัดในตัวสร้างที่this.handleChange.bind(this);ควรจะthis.handleChange = this.handleChange.bind(this);
Will Shaver

สำหรับคนที่ชอบฉันที่ถามพวกเขาว่า ... หมายถึงอะไร: reactjs.org/docs/jsx-in-depth.html#spread-attributes
talsibony

@talsibony - นั่นคือตัวดำเนินการสเปรด แต่ในโค้ดตัวอย่างของฉันมันแค่หมายถึงการแทรกรหัสอื่น ๆ ที่นี่ !
Andy Lorenz

@AndyLorenz ดังนั้นในกรณีนี้ฉันอยากจะแนะนำให้ลบ ... :) หรือเพียงแค่เขียนความคิดเห็นเช่น // ส่วนที่เหลือของรหัสของคุณ
talsibony

8

นี่คือตัวอย่างล่าสุดของวิธีการทำ จากเอกสารตอบกลับรวมถึงไวยากรณ์เมธอด "fat-arrow" ที่มีผลผูกพันอัตโนมัติ

class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 'coconut'};
  }

  handleChange = (event) =>
    this.setState({value: event.target.value});

  handleSubmit = (event) => {
    alert('Your favorite flavor is: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Pick your favorite flavor:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
          </select>
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
} 

4

เพียงเพิ่มตัวเลือกแรกของแท็กที่คุณเลือก:

<option disabled hidden value=''></option>

สิ่งนี้จะกลายเป็นค่าเริ่มต้นและเมื่อคุณเลือกตัวเลือกที่ถูกต้องจะถูกกำหนดในสถานะของคุณ


1
***Html:***
<div id="divContainer"></div>

var colors = [{ Name: 'Red' }, { Name: 'Green' }, { Name: 'Blue' }];
var selectedColor = 'Green';

ReactDOM.render(<Container></Container>, document.getElementById("divContainer"));

var Container = React.createClass({
    render: function () {
        return (
        <div>            
            <DropDown data={colors} Selected={selectedColor}></DropDown>
        </div>);
    }
});

***Option 1:***
var DropDown = React.createClass(
{
    render: function () {
        var items = this.props.data;
        return (
        <select value={this.props.Selected}>
            {
                items.map(function (item) {
                    return <option value={item.Name }>{item.Name}</option>;
                })
            }
        </select>);
    }
});

***Option 2:***
var DropDown = React.createClass(
{
    render: function () {
        var items = this.props.data;
        return (
        <select>
            {
                items.map(function (item) {
                    return <option value={item.Name} selected={selectedItem == item.Name}>{item.Name}</option>;
                })
            }
        </select>);
    }
});

***Option 3:***
var DropDown = React.createClass(
    {
        render: function () {
            var items = this.props.data;
            return (
            <select>
                {
                    items.map(function (item) {

                                            if (selectedItem == item.Name)
                    return <option value={item.Name } selected>{item.Name}</option>;
                else
                    return <option value={item.Name }>{item.Name}</option>;
                    })
                }
            </select>);
        }
    });

1
แม้ว่าจะไม่ได้รับคำอธิบาย แต่ก็ไม่จำเป็นต้องใช้จริงๆ วิธีการหลายวิธีในการแก้ไขปัญหาเดียวกันนี้เป็นข้อมูลเชิงลึกที่เป็นประโยชน์จริง ๆ ขอบคุณ
DJ2

0

ฉันมีปัญหากับ<select>แท็กที่ไม่อัปเดตให้ถูกต้อง<option>เมื่อสถานะมีการเปลี่ยนแปลง ปัญหาของฉันดูเหมือนว่าถ้าคุณแสดงสองครั้งติดต่อกันอย่างรวดเร็วเป็นครั้งแรกที่ไม่มีการเลือกล่วงหน้า<option>แต่เป็นครั้งที่สองที่มี<select>แท็กหนึ่งแท็กจะไม่อัปเดตสำหรับการเรนเดอร์ครั้งที่สอง

ผมพบว่าวิธีแก้ปัญหานี้โดยใช้refs คุณต้องได้รับการอ้างอิงถึง<select>โหนดแท็กของคุณ(ซึ่งอาจซ้อนอยู่ในส่วนประกอบบางส่วน) จากนั้นอัปเดตvalueคุณสมบัติด้วยตนเองในcomponentDidUpdatehook

componentDidUpdate(){
  let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
  selectNode.value = this.state.someValue;
}

0

โพสต์คำตอบที่คล้ายกันสำหรับ MULTISELECT / optgroups:

render() {
  return(
    <div>
      <select defaultValue="1" onChange={(e) => this.props.changeHandler(e.target.value) }>
        <option disabled="disabled" value="1" hidden="hidden">-- Select --</option>
        <optgroup label="Group 1">
          {options1}
        </optgroup>
        <optgroup label="Group 2">
          {options2}
        </optgroup>
      </select>
    </div>
  )
}

0

ฉันมีทางออกที่ง่ายคือการติดตาม HTML พื้นฐาน

<input
  type="select"
  defaultValue=""
  >
  <option value="" disabled className="text-hide">Please select</option>
  <option>value1</option>
  <option>value1</option>
</input>

.text-hide เป็นคลาสของ bootstrap หากคุณไม่ได้ใช้ bootstrap นี่คือ:

.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}

-1

ฉันได้รับปัญหาที่คล้ายกันโดยการตั้งค่า defaultProps:

ComponentName.defaultProps = {
  propName: ''
}

<select value="this.props.propName" ...

ดังนั้นตอนนี้ฉันหลีกเลี่ยงข้อผิดพลาดในการรวบรวมถ้าเสาของฉันไม่มีอยู่จนกระทั่งติดตั้ง


นั่นไม่ได้แก้ปัญหาจริงๆ คุณจะได้รับสิ่งนี้: คำเตือน: ประเภท prop ล้มเหลว: คุณระบุvalueprop ให้กับฟิลด์แบบฟอร์มโดยไม่มีonChangeตัวจัดการ สิ่งนี้จะแสดงฟิลด์แบบอ่านอย่างเดียว defaultValueถ้าเขตควรจะใช้งานไม่แน่นอน มิฉะนั้นชุดทั้งหรือonChange readOnly
เจสันข้าว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.