显示/隐藏数据与fetch API作出反应

时间:2016-12-23 06:36:36

标签: json reactjs fetch

我正在尝试从API获取数据并在反应时显示/隐藏它。我得到的数据很好,但隐藏按钮不起作用。始终显示数据。我的反应比较新,真的很想学习它。这是我的代码:(如果有人建议我在哪里可以了解更多有关网络反应的信息,那就太棒了)

import React from 'react';
import {render} from 'react-dom';

class Series extends React.Component {
    constructor() {
        super();
        this.state = {
            showSeries: false
        };
    }

    render() {
        const serieses = this._GetList();
        let seriesNodes;
        let buttonText = 'Show Series';
        if (this.state.showMangas) {
            seriesNodes = <div>{serieses}</div>;
            buttonText = 'Hide Series';

        }
        return (<div>
                <button onClick={this._handleClick.bind(this)}>{buttonText}</button>
                {seriesNodes}
            </div>
        );
    }

    _GetList() {
        var myInit = {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'text/plain'
            }),
        }
        var myRequest = new Request('data.json', myInit);
        fetch(myRequest)
            .then(function (response) {
                return response.json()
                    .then(function (json) {
                        console.log(json)
                        json.manga.map((item) => {
                            var li = document.createElement('li');
                        //  for (var i = 0; i < (item).length; i++) {
                                li.innerHTML = 'Name: ' + item.t + ', Genre: ' + item.c + ' Hit Count: ' + item.h;
                                document.getElementById('myDiv').appendChild(li);
                        //  }
                        })
                    })

            })
            .catch(function (error) {
                console.log('There has been a problem with your fetch operation: ' + error.message);
            });

        return (
            <div>
                <div></div>
            </div>
        )
    }

    _handleClick() {
        this.setState({showSeries: !this.state.showSeries});
    }
}
render( <Series />, document.getElementById('myDiv'));

1 个答案:

答案 0 :(得分:1)

在React的思考方面,你会发现这个问题。不要使用document.CreateElement()来创建div。这些不是您在React中想要的虚拟元素。你也不在React中动态创建html,你动态地在html中创建数据或者渲染那个html(booleans)的条件。

注意:如果您想多次执行API调用,则应使用React lifecycle methods,可能还需componentDidUpdate。你不应该在render()中调用api方法,因为这只应该用于构建虚拟html。

在第一次渲染时,buttonText将是未定义的,但我们不在乎

import React from 'react';
import {render} from 'react-dom';

const SHOWN_BUTTON_TEXT = "Show Series";
const HIDDEN_BUTTON_TEXT = "Hide Series";

class Series extends React.Component {
    constructor() {
        super();

        //Bind in the constructor instead so we don't create a new function every render like you were doing
        this._handleOnClick = this._handleOnClick.bind(this);
        this.fetchSeries= this.fetchSeries.bind(this);

        this.state = {
            buttonText: HIDDEN_BUTTON_TEXT,
            showSeries: false,
            listItems: {}
        };
    }

    render() {
        return (<div>
                    <button onClick={this._handleOnClick}>{this.state.buttonText}</button>
                    <ul>
                        {this.state.listItems.map(item => <Item {...item}/>)}
                    </ul>
                </div>
        );
    }
    _handleOnClick() {
        this.setState({showSeries: !this.state.showSeries});
        this.setState({buttonText: SHOWN_BUTTON_TEXT ? this.state.showSeries : HIDDEN_BUTTON_TEXT})
    }
    fetchSeries() {
       var myInit = {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'text/plain'
            }),
        }
        var myRequest = new Request('data.json', myInit);
        fetch(myRequest)
            .then(function (response) {
                return response.json()
                    .then(function (json) {
                        this.setState({listItems: json});
                    }.bind(this)

            })
            .catch(function (error) {
                console.log('There has been a problem with your fetch operation: ' + error.message);
            });
    }
    componentDidMount() {
        this.fetchSeries();
    }
}

Stateless function

//Instead of passing in props as argument we can pass in the values directly
function Item ({t, c, h}) {
    return (
        <li>
            Name: {t},
            Genre: {c},
            Hit Count: {h}
        </li>
    );
}

render( <Series />, document.getElementById('myDiv'));