我有一个基本的ReactJS
应用,其中包含一个自定义Select
,该应用会在2秒后填充。
./ src / controls / Select / Select.js
import React, { Component } from 'react';
import './Select.scss';
class Select extends Component {
constructor(props) {
super(props);
let { name, value, data, className, onChange, onFocus, onBlur, ...controlProps } = this.props;
this.name = name;
this.onChange = onChange || ((e) => { });
this.onFocus = onFocus || ((e) => { });
this.onBlur = onBlur || ((e) => { });
this.controlProps = controlProps;
this.state = {
[name]: value,
className,
};
}
componentDidMount() {
this.handleChange({ target: this.refs.select });
}
handleChange = (e) => {
let target = e.target;
let name = target.name;
let value = target.value;
this.setState({
[name]: value,
});
this.onChange(e);
};
render() {
let data = this.props.data || [];
return (
<div className="control-select" {...this.controlProps}>
<div className="custom-dropdown custom-dropdown--grey">
<select
ref="select"
name={this.name}
className="custom-dropdown__select custom-dropdown__select--grey"
value={this.state[this.name]}
onChange={this.handleChange}
>
{
data.map((elem, index) => {
return <option value={elem.value} key={index}>{elem.text}</option>
})
}
</select>
</div>
</div>
);
}
}
export default Select;
我也有主要的App
:
./ src / index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Select from './controls/Select/Select';
import './styles.scss';
export default class Lab extends Component {
constructor(props) {
super(props);
this.state = {
selection: '',
options: [],
}
setTimeout(() => {
this.setState({
options: [
{ "value": "option_01", "text": "Option 01" },
{ "value": "option_02", "text": "Option 02" },
{ "value": "option_03", "text": "Option 03" },
{ "value": "option_04", "text": "Option 04" },
{ "value": "option_05", "text": "Option 05" },
],
});
}, 2000);
}
handleChange = (e) => {
let target = e.target;
let name = target.name;
let value = target.value;
this.setState({
[name]: value,
});
};
render() {
return (
<div className="App">
<div style={{ borderBottom: '1px solid #ddd', margin: '20px 0 10px 0' }}>
The value on the select box should appear on the yellow box automatically.
</div>
{/* BEGIN OF WORKING AREA */}
<table style={{ display: 'inline-block', margin: '0 0 10px', border: 'none' }}>
<tbody>
<tr>
<td style={{ width: '218px', border: 'none' }}>
<Select
name="selection"
value={this.state.selection}
data={ this.state.options.map(elem => { return { value: elem.value, text: elem.text }; }) }
style={{ width: '100%' }}
onChange={ this.handleChange }
/>
</td>
<td style={{ width: '100px', border: 'none', color: '#b00', backgroundColor: '#ffa', textAlign: 'center', fontSize: '14px' }}>
<span>{this.state.selection}</span>
</td>
</tr>
</tbody>
</table>
{/* END OF WORKING AREA */}
</div>
);
}
}
if (document.getElementById('root')) {
ReactDOM.render(<Lab />, document.getElementById('root'));
}
我需要的是,它是在填充自定义Select
之后,它将其值传播到父组件state
。现在,当它填充时,它不会执行此操作(您可以使用空白的黄色框进行检查)。另一方面,如果更改该Select
上的选项,则其值将成功传播。
在这里,您可以使用它的Codesandbox.io
:
https://codesandbox.io/s/73z220z11q
如果可能,请提供您的解决方案的分叉式Codesandbox.io
。
这就是我要发生的事情:
[更新]
这里有我关注的真实代码:
https://codesandbox.io/s/xl6zxz0v84
如果用户在Select
上手动选择一个选项,则该值将正确设置为selectedTheme
(在App状态下)。那部分很好。
我想要的是如果用户没有手动选择任何内容,则选择项上显示的值应设置为selectedTheme
。当前未设置任何内容(如果用户不进行交互)。
您可以通过单击selectedTheme
按钮来检查Submit
的值。
谢谢!
答案 0 :(得分:0)
我认为问题在于您如何直接从自定义选择的handleChange
调用componentDidMount
。当时,您的target
确实没有value
的原因是您要根据Redux状态设置选项。
要解决此问题,可以在要从componentWillReceiveProps
获取选项的组件中使用Redux
,并在获取更新时手动更改state.selection
。像这样:
componentWillReceiveProps(nextProps) {
if (this.props.options.length !== nextProps.options.length) {
this.setState({ selection: nextProps.options[0].value });
}
}
答案 1 :(得分:0)
嗨,错误是选择元素仅在触发onChange函数时才设置选择。
如果需要,在填充时需要手动设置或在选择状态下设置默认值。
//set the selection default state at the time of setting options in constructor.
constructor(props) {
super(props);
this.state = {
selection: "",
options: []
};
setTimeout(() => {
this.setState(
{
options: [
{ value: "option_01", text: "Option 01" },
{ value: "option_02", text: "Option 02" },
{ value: "option_03", text: "Option 03" },
{ value: "option_04", text: "Option 04" },
{ value: "option_05", text: "Option 05" }
]
},
() => this.setState({ selection: this.state.options[0].value })
);
}, 2000);
}