React:如何将选项值映射到状态键?

时间:2018-03-14 20:26:36

标签: javascript reactjs

目前正在掌握JS和React。我想将所选选项中的值映射到this.state.transcode_profile。我尝试使用与input标签上使用的方法相同的方法,但遗憾的是这不起作用。

这是代码,我做错了什么?

import React, { Component } from "react";

    const ProfileList = ({profiles}) => (
        <select name="transcode_profile"
                id="transcode_profile"
                onChange={this.onChange}>
            <option value="-----">----</option>
            {profiles.map(profile => <option value={profile.name}>{profile.name}</option>)}
        </select>
    );

    const url = 'http://localhost:8000/api/tasks/';

    class Submit_job extends Component {

        constructor(){
            super();
            this.state = {
                "profiles": [],
                "material_id": null,
                "transcode_profile": null,
                "start_date": null,
                "end_date": null,
            };
        };

        componentDidMount(){
            fetch("http://localhost:8000/api/profiles/")
                .then(response => response.json())
                .then(response => this.setState({ profiles: response}))
        }

        onChange = (e) => {
            // Because we named the inputs to match their corresponding values in state, it's
            // super easy to update the state
            const state = this.state;
            state[e.target.name] = e.target.value;
            this.setState(state);
        };

        handleChange(e){
            this.setState({selectValue:e.target.value});
        };

        postData = (e) => {
            e.preventDefault();
            // Default options are marked with *
            return fetch(url, {
                body: JSON.stringify({status: 'submitted',
                    video_data: {material_id: this.state.material_id},
                    profile_data: {name: this.state.transcode_profile },
                    start: this.state.start_date,
                    end: this.state.end_date,
                    user: 'Foobar'}), // must match 'Content-Type' header
                cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
                credentials: 'same-origin', // include, same-origin, *omit
                headers: {
                    'user-agent': 'Mozilla/4.0 MDN Example',
                    'content-type': 'application/json'
                },
                method: 'POST', // *GET, POST, PUT, DELETE, etc.
                mode: 'cors', // no-cors, cors, *same-origin
                redirect: 'follow', // *manual, follow, error
                referrer: 'no-referrer', // *client, no-referrer
            })
                .then(response => response.json()) // parses response to JSON
        };

        render() {
            return (
                <div>
                    <h2>Submit Job</h2>
                    <form onSubmit={this.postData}>
                        <label htmlFor="material_d">Material ID:</label>
                        <input id="material_id"
                               type="text"
                               name="material_id"
                               onChange={this.onChange}
                               required/>
                        <br/>
                        <label htmlFor={"transcode_profile"}>Transcode Profile:</label>
                        <ProfileList profiles={this.state.profiles}/>
                        <br/>
                        <label htmlFor="start_date">Start Date:</label>
                        <input type="text"
                               name="start_date"
                               id="start_date"
                               onChange={this.onChange}
                               required/>
                        <br/>
                        <label htmlFor="end_data">End Date:</label>
                        <input type="text"
                               name="end_date"
                               id="end_date"
                               onChange={this.onChange}
                               required/>
                        <br/>

                        <button>Submit</button>
                    </form>

                </div>

            );
        }
    }

    export default Submit_job;

修改 这就是我如何运作的。

import React, { Component } from "react";

const ProfileList = ({onChange, profiles, value}) => (
    <select name="transcode_profile"
            id="transcode_profile"
            onChange={onChange}
            value={value}>
        <option value="-----">----</option>
        {profiles.map(profile => <option value={profile.name}>{profile.name}</option>)}
    </select>
);

const url = 'http://localhost:8000/api/tasks/';

class Submit_job extends Component {

    constructor(){
        super();
        this.state = {
            "profiles": [],
            "material_id": null,
            "transcode_profile": null,
            "start_date": null,
            "end_date": null,
        };
    };

    componentDidMount(){
        fetch("http://localhost:8000/api/profiles/")
            .then(response => response.json())
            .then(response => this.setState({ profiles: response}))
    }

    onChange = (e) => {
        // Because we named the inputs to match their corresponding values in state, it's
        // super easy to update the state
        const state = this.state;
        state[e.target.name] = e.target.value;
        this.setState(state);
    };

    postData = (e) => {
        e.preventDefault();
        // Default options are marked with *
        return fetch(url, {
            body: JSON.stringify({status: 'submitted',
                video_data: {material_id: this.state.material_id},
                profile_data: {name: this.state.transcode_profile },
                start: this.state.start_date,
                end: this.state.end_date,
                user: 'Lewis'}), // must match 'Content-Type' header
            cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
            credentials: 'same-origin', // include, same-origin, *omit
            headers: {
                'user-agent': 'Mozilla/4.0 MDN Example',
                'content-type': 'application/json'
            },
            method: 'POST', // *GET, POST, PUT, DELETE, etc.
            mode: 'cors', // no-cors, cors, *same-origin
            redirect: 'follow', // *manual, follow, error
            referrer: 'no-referrer', // *client, no-referrer
        })
            .then(response => response.json()) // parses response to JSON
    };

    render() {
        return (
            <div>
                <h2>Submit Job</h2>
                <form onSubmit={this.postData}>
                    <label htmlFor="material_d">Material ID:</label>
                    <input id="material_id"
                           type="text"
                           name="material_id"
                           onChange={this.onChange}
                           required/>
                    <br/>
                    <label htmlFor={"transcode_profile"}>Transcode Profile:</label>
                    <ProfileList
                        onChange={this.onChange}
                        profiles={this.state.profiles}
                    />
                    <br/>
                    <label htmlFor="start_date">Start Date:</label>
                    <input type="text"
                           name="start_date"
                           id="start_date"
                           onChange={this.onChange}
                           required/>
                    <br/>
                    <label htmlFor="end_data">End Date:</label>
                    <input type="text"
                           name="end_date"
                           id="end_date"
                           onChange={this.onChange}
                           required/>
                    <br/>

                    <button>Submit</button>
                </form>

            </div>

        );
    }
}

export default Submit_job;

2 个答案:

答案 0 :(得分:1)

select也应该传递值,因此它知道选择了哪个选项:

const ProfileList = ({ onChange, profiles, value }) => (
    <select
      name="transcode_profile"
      id="transcode_profile"
      onChange={onChange}
      value={value}
    >
        <option value="-----">----</option>
        {profiles.map(profile => <option value={profile.name}>{profile.name}</option>)}
    </select>
);

然后在渲染ProfileList时,我们应该传递selectValue状态,​​以及handleChange回调。

<ProfileList 
  onChange={this.handleChange} 
  profiles={this.state.profiles} 
  value={this.state.selectValue} 
/>

您还应该在构造函数中设置默认状态以及selectValue

constructor(){
  super();
  this.state = {
    "profiles": [],
    "material_id": null,
    "transcode_profile": null,
    "start_date": null,
    "end_date": null,
    "selectValue": "-----"
  };
}

如果您尚未阅读表单上的React文档,我会推荐它们:https://reactjs.org/docs/forms.html#the-select-tag

答案 1 :(得分:1)

 handleChange = (e, {value}) => {
  this.setState({selectValue:value});
 };

这也可以写成

handleChange = (e, data) => {
  this.setState({selectValue:data.value});
};

对于某些元素,Semantic-UI-React要求您首先提供事件,还要提供包含所需数据的第二个参数。这是一个众所周知的限制。