可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In a React component for a <select> menu, I need to set the selected attribute on the option that reflects the application state.
In render(), the optionState is passed from the state owner to the SortMenu component. The option values are passed in as props from 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
However that triggers a syntax error on JSX compilation.
Doing this gets rid of the syntax error but obviously doesn't solve the problem:
var selected = (optionState === option.value) ? 'selected' : 'false'; <option value={option.value} selected={selected}>{option.label}</option>
I also tried this:
var selected = (optionState === option.value) ? true : false; <option value={option.value} {selected ? 'selected' : ''}>{option.label}</option>
Is there a recommended way of solving this?
回答1:
React automatically understands booleans for this purpose, so you can simply write (note: not recommended)
<option value={option.value} selected={optionsState == option.value}>{option.label}</option>
and it will output 'selected' appropriately.
However, React makes this even easier for you. Instead of defining selected on each option, you can (and should) simply write value={optionsState} on the select tag itself:
<select value={optionsState}> <option value="A">Apple</option> <option value="B">Banana</option> <option value="C">Cranberry</option> </select>
More info at http://facebook.github.io/react/docs/forms.html#why-select-value.
回答2:
You could do what React warns you when you try to set the "selected" property of the <option>:
Use the defaultValue or value props on <select> instead of setting selected on <option>.
So, you can use options.value on the defaultValue of your select
回答3:
Here is a complete solution which incorporates the best answer and the comments below it (which might help someone struggling to piece it all together):
in main component:
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} onChange{this.handleChange} /> ) } }
included component (which is now a stateless functional):
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> )
the main component maintains the selected value for fruit (in state), the included component displays the select element and updates are passed back to the main component to update its state (which then loops back to the included component to change the selected value).
Note the use of a name prop which allows you to declare a single handleChange method for other fields on the same form regardless of their type.
回答4:
I've had a problem with <select> tags not updating to the correct <option> when the state changes. My problem seemed to be that if you render twice in quick succession, the first time with no pre-selected <option> but the second time with one, then the <select> tag doesn't update on the second render, but stays on the default first .
I found a solution to this using refs. You need to get a reference to your <select> tag node (which might be nested in some component), and then manually update the value property on it, in the componentDidUpdate hook.
componentDidUpdate(){ let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag); selectNode.value = this.state.someValue; }
回答5:
***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>); } });
回答6:
Posting a similar answer for 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> ) }
回答7:
Simply add as first option of your select tag:
<option disabled hidden value=''></option>
This will become default and when you'll select a valid option will be setted on your state
回答8:
Here is the latest example of how to do it , From react docs
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: 'coconut'}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } 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 La Croix 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> ); } }
回答9:
I have a simple solution is following the HTML basic.
<input type="select" defaultValue="" > <option value="" disabled className="text-hide">Please select</option> <option>value1</option> <option>value1</option> </input>
.text-hide is a bootstrap's class, if you not using bootstrap, here you are:
.text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; }
回答10:
I got around a similar issue by setting defaultProps:
ComponentName.defaultProps = { propName: '' }
<select value="this.props.propName" ...
So now I avoid errors on compilation if my prop does not exist until mounting.