javascript - React 中 <select> 时 onChange 事件无法按预期工作

标签 javascript select onchange reactjs

我有一个表格,在编辑时显示有关票证的信息。票证作为对象从 API 接收,在我的例子中是 data (例如 apiUrl: {tickets: '/api/tickets'} )。 data包含工单的所有默认状态,例如:优先级、状态和类型。所有API数据都在TicketForm中管理成分。参见下面的组件代码:

class TicketForm extends Component {

    constructor(props) {
        super(props);
        this.handleSelectChange = this.handleSelectChange.bind(this);
        this.save = this.save.bind(this);
        this.state = {
            apiUrl: {tickets: '/api/tickets'},
            data: {
                id: '',
                ticket: '',
                key: '',
                priority: {
                    id: "",
                    name: ""
                },
                status: {
                    id: "",
                    name: ""
                },
                type: {
                    id: "",
                    name: ""
                }
            },
            priority: [],
            status: [],
            type: []
        };
    }

    componentWillMount() {
        //Getting the JSON from APIs
    }

    save() {
        //Saving/Updating data to server
    }

    handleSelectChange(e) {
        for (var i = 0; i < this.state[e.target.name].length; i++) {
            if (this.state[e.target.name][i].id == e.target.value) {
                this.state.data[e.target.name] = this.state[e.target.name][i];
            }
        }
        this.setState({data: this.state.data});
    }

    render() {
        return (
            <table className="table table-striped">
                <tbody>
                <tr>
                    <th>Priority:</th>
                    <td>
                        <SelectForm
                            onChange={this.handleSelectChange}
                            name="priority"
                            options={this.state.priority}
                            selected={this.state.data.priority.name}/>
                    </td>
                </tr>
                <tr>
                    <th>Status:</th>
                    <td>
                        <SelectForm
                            onChange={this.handleSelectChange}
                            name="status" options={this.state.type}
                            selected={this.state.data.type.name}/>
                    </td>
                </tr>
                <tr>
                    <th>Type:</th>
                    <td>
                        <SelectForm
                            onChange={this.handleSelectChange}
                            name="type"
                            options={this.state.status}
                            selected={this.state.data.status.name}/>
                    </td>
                </tr>
                </tbody>

            </table>
        )

    }
}

我想在单击元素时编辑此信息,然后渲染 <select>包含从 API 作为数组接收的一些选项,以及可应用于字段的不同选项:优先级、状态和类型。这是一个与上面不同的 API(例如 apiUrl: {tickets: '/api/tickets/type'} )。选择option后,我从所选对象中获取数据并将其替换为初始 data目的。请参阅SelectForm组件如下:

export default class SelectForm extends Component {

    constructor(props) {
        super(props);
        this.state = {
            edit: false
        };
    }

    editProject() {
        this.setState({edit: true});
    }

    blurProject() {
        this.setState({edit: false});
    }

    handleChange(e) {
        if (this.props.onChange) {
            this.props.onChange(e);
        }
    }

    renderForm() {
        return (
            <select
                className="form-control"
                name={this.props.name}
                onChange={this.handleChange.bind(this)}
                onBlur={this.blurProject.bind(this)}>
                {(Array.isArray(this.props.options) && this.props.options.length > 0) ? this.props.options.map(option => {
                    return (
                        <option key={option.id} value={option.id}>{option.name}</option>
                    )
                }) : (<option>No Options Found</option>)}
            </select>
        )
    }

    render() {
        if (this.state.edit) {
            return this.renderForm();
        } else {
            return (
                <p onClick={this.editProject.bind(this)}>{this.props.selected}</p>
            )
        }
    }
}

我正在尝试处理更改事件。当从选择中选择其他选项时,根据所选选项设置状态,并在选择该选项后在字段中显示新状态。

我以为我已经实现了这一目标,但不知何故,它们之间的场表现得很奇怪。优先级似乎工作得很好,但每当我从类型中选择一个选项时,它的状态就会改变,甚至无需触摸它,反之亦然。

我无法理解问题所在,请查看handleSelectChange()函数逻辑,并告诉我做错了什么,或者这个问题的一些解决方案。

更新:

在答案中发现,该文档关于 Immutability Helpers会有帮助的。我尝试使用链接中的一个示例,但得到了相同的结果。请看一下代码并让我知道我做得是否正确:

handleSelectChange(e) {
    for (var i = 0; i < this.state[e.target.name].length; i++) {
        if (this.state[e.target.name][i].id == e.target.value) {
            var newState = update(this.state, {
                data: {
                    [e.target.name]: { $set: this.state[e.target.name][i] }
                }
            });
        }
    }
    this.setState(newState);
}

最佳答案

您需要使用immutable helpers或者像这样创建新对象:

this.setState(Object.assign({}, this.state, newState))

UPD: 尝试做这样的事情:

handleSelectChange(e) {
  const data = Object.assign({}, this.state.data)

  data[e.target.name] = e.target.value;
  for (var i = 0; i < data[e.target.name].length; i++) {
      if (data[e.target.name][i].id == e.target.value) {
          data[e.target.name] = data[e.target.name][i];
      }
  }

  this.setState({ data });
}

关于javascript - React 中 <select> 时 onChange 事件无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38498417/

相关文章:

javascript - 根据条件禁用单击/选择下拉列表中的某些选项

javascript - 如何选择焦点文本区域中的所有文本(在 Safari 中)

php - 如何在 1 个 http 请求下上传多个文件

javascript - 在jquery中序列化两个复选框

javascript - 在 Iframe 中加载响应式网站

javascript - jQuery 'change' 事件

excel - VBA 防止用户仅引用初始单元格值更改单元格值

javascript - es6 vanilla javascript 中的 Ajax 请求

javascript - 编辑textContent或innerHTML会杀死eventListener

javascript - 根据选择更改选定值