如何构建依赖于json

时间:2018-04-01 03:33:06

标签: reactjs

我想要一个典型的“编辑”表单(对API进行GET以预先填充表单,然后用户可以编辑表单,然后提交按钮执行POST)

听起来很简单,但详情如下:A GET /getformdata会返回此信息:

{
  "mytype": "article",
  "title": "I feel bad that this is not one of my better SO questions",
  "body": "Just get to the point",
  "author": "Bob Jones",
  "Latitude": 0,
  "Longitude": 0,
  "Startdate": ""
}

也可以返回:

{
  "mytype": "eventlisting",
  "title": "Annual Gala",
  "body": "You have to be snooty",
  "author": "Martha Stewart",
  "Latitude": 51.507351,
  "Longitude": -0.127758,
  "Startdate": "2019-04-23T18:25:43.511Z"
}

我想要呈现以下html 的表单,如果它是一篇文章:

<h2>Edit Article</h2>
<form>
  Headline:  <input type="text" name="title" value="I feel bad that this is not one of my better SO questions">
  Article Body:<input type="text" name="body" value="Just get to the point">
</form>

如果是一个事件,请渲染以下html

<h2>Edit Event</h2>
<form>
  Event Title:  <input type="text" name="title" value="I feel bad that this is not one of my better SO questions">
  Event Body:<input type="text" name="body" value="Just get to the point">
  Event Location:<input <!-- A google map shows up here based on lat long -->>
  Event Start Date:<input <!-- A calendar date time picker shows up here -->>
</form>

我开始学习反应,我认为谷歌地图,日历日期时间选择器可能是组件的良好候选人。我想我需要为每种类型定义一个模板,并希望编码优雅。我可以使用jquery做到这一点,但我很确定有一个很好的方法来做到这一点,但我不清楚如何处理它。

我很高兴指出我有正确的方向,有一些示例代码..

1 个答案:

答案 0 :(得分:1)

这里有一个令人惊讶的基础。首先,要回答你的问题,我们的想法是为文章和事件列表设置单独的组件,并根据API响应选择要呈现的组件,使用类似这样的代码:

render() {

    var object = <p>Loading...</p>;

    if( this.state.object ) {
        if( this.state.objectType === "article" ) {
            object = <Article article={this.state.object} />;
        }
        else if( this.state.objectType === "eventlisting" ) {
            object = <EventListing listing={this.state.object} />;
        }
    }

    return (
        <div>
            {object}
        </div>
   );
}

但是从那里到工作解决方案还有很多,所以这里有一个基于使用create-react-app创建的小应用程序的更完整示例:

<强> App.js

import React, { Component } from 'react';
import Article from './Article';
import EventListing from './EventListing';

import './App.css';

class App extends Component {
    constructor(props) {
        super(props);
        this.state = { object: null, objectType: null };

        this.handleSubmitArticle    = this.handleSubmitArticle.bind(this);
        this.handleSubmitEvent      = this.handleSubmitEvent.bind(this);
    }

    componentDidMount() {

        // Hard-coded response here, but would be fetched from API. This is a good
        // way to start out to get the hang of React (and for prototyping), but in 
        // the long run you should take a look at Redux and use that to store your
        // API responses and simply pass them in as props to your components

        let apiResponse = {
            "mytype": "article",
            "title": "I feel bad that this is not one of my better SO questions",
            "body": "Just get to the point",
            "author": "Bob Jones",
            "Latitude": 0,
            "Longitude": 0,
            "Startdate": ""
        };

        this.setState( {object: apiResponse, objectType: apiResponse.mytype } );
    }

    handleSubmitArticle(article) {
        // Call API or pass on to parent/container
    }

    handleSubmitEvent(event) {
        // Call API or pass on to parent/container
    }

    render() {

        var object = <p>Loading...</p>;

        if( this.state.object ) {
            if( this.state.objectType === "article" ) {
                object = <Article article={this.state.object} 
                            onSubmit={this.handleSubmitArticle}
                         />;
            }
            else if( this.state.objectType === "eventlisting" ) {
                object = <EventListing listing={this.state.object} 
                            onSubmit={this.handleSubmitEvent}
                          />;
            }
        }

        return (
            <div>
                {object}
            </div>
       );
    }
}

export default App;

<强> EventListing.js

import React, { Component } from 'react';

class EventListing extends Component {

    constructor(props) {
        super(props);
        this.state = { listing: this.props.listing };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(event) {
        event.preventDefault();
        this.props.onSubmit(this.state.listing);
    }

    render() {
        return (
            <div className="event">
                <h2>Edit Event</h2>
                <form onSubmit={this.handleSubmit}>
                    Event Title:  
                    <input type="text" name="title" 
                        value={this.state.listing.title}
                        onChange={this.handleChange}/>

                    Event Body:
                    <input type="text" name="body" 
                        value={this.state.listing.body}
                        onChange={this.handleChange}/>
                    Event Location:<input name="location"
                        value={this.state.listing.location}
                        onChange={this.handleChange} />
                    Event Start Date:<input name="Startdate"
                        value={this.state.listing.Startdate}
                        onChange={this.handleChange} />
                  <button type="submit">Save</button>
                </form>
            </div>
        );
    }
}

export default EventListing;

<强> Article.js

import React, { Component } from 'react';

class Article extends Component {

    constructor(props) {
        super(props);
        this.state = { article: this.props.article };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(event) {
        event.preventDefault();
        this.props.onSubmit(this.state.article);
    }


    render() {
        return (
            <div className="article">
                <h2>Edit Article</h2>
                <form onSubmit={this.handleSubmit}>
                  Headline:  
                  <input type="text" name="title" 
                      value={this.state.article.title}
                      onChange={this.handleChange}/>
                  Article Body:
                  <input type="text" name="body" 
                      value={this.state.article.body}
                      onChange={this.handleChange}/>
                  <button type="submit">Save</button>
                </form>
            </div>
        );
    }
}

export default Article;

这段代码中有几个关键的React概念,所以这里有一些链接,你可能会发现有助于理解这段代码的作用: