React有时候不会渲染按钮?

时间:2016-11-14 22:36:42

标签: javascript facebook reactjs

我刚刚开始学习React以及如何将其与不同的API集成。我的页面现在所做的是从输入字段中获取信息,React应该在视图部分中呈现它。但是,有时(如果我继续刷新)React应该呈现的按钮不会显示并返回错误:

Uncaught TypeError: Cannot read property 'map' of undefined

另外,我检查了HTML,并且在用户信息的所有div之前有一个空div。到目前为止,我试图实现的目标是有效的,但只有在"添加信息"按钮决定显示。

我在这里上传了它,如果它有助于可视化我的问题:testing.nicholasdrzewiecki.ca - 如果你有时保持清醒,那么"添加信息"按钮没有出现。 Facebook登录没有设置,但点击它以显示创建按钮,输入,用随机信息填充输入,然后单击"添加信息"。

我的巴贝尔代码如下:

// jshint ignore: start

/* React Module */
var DisplayInformation = React.createClass({
  addUserInfo: function() {
    this.props.funcAddUser(document.getElementById("inputName").value);
    this.props.funcAddUser(document.getElementById("inputTitle").value);
    this.props.funcAddUser(document.getElementById("inputStatus").value);
    this.props.funcAddUser(document.getElementById("inputLatitude").value);
    this.props.funcAddUser(document.getElementById("inputLongitude").value);
  },

  render: function() {
    console.log(this.props.list);

    var self = this;
    var arr = self.props.list.map(function(obj) {
      return (
        <div>{obj.name}</div>
      )
    });

    return (
      <div>
        {arr}
        <button onClick={this.addUserInfo}>Add Information</button>
      </div>
    );
  }
});

var Container = React.createClass({
  getInitialState: function() {
    return {
      ulist: window.userInformation
    }
  },

  addUser: function(name, title, status, latitude, longitude) {
    var obj = {
      name: name,
      title: title,
      status: status,
      latitude: latitude,
      longitude: longitude
    }
    this.state.ulist.push(obj);
    this.setState({
      ulist: this.state.ulist
    });
  },

  render: function() {
    return (
      <div>
        <DisplayInformation list={this.state.ulist} funcAddUser={this.addUser} />
      </div>
    )
  }
});

ReactDOM.render(
  <Container />,
  document.getElementById("displayReact")
);

我使用Facebook和Google Maps API的其他JavaScript文件如下所示:

/* jshint loopfunc: true */

$(document).ready(function() {

    var buttonFacebookLogin = document.getElementById("buttonFacebookLogin");
    var buttonCreate = document.getElementById("buttonCreate");
    var buttonView = document.getElementById("buttonView");
    var inputName = document.getElementById("inputName");
    var inputTitle = document.getElementById("inputTitle");
    var inputImage = document.getElementById("inputImage");
    var inputStatus = document.getElementById("inputStatus");
    var inputLatitude = document.getElementById("inputLatitude");
    var inputLongitude = document.getElementById("inputLongitude");
    var storeInformation = document.getElementById("storeInformation");
    var displayInformation = document.getElementById("displayInformation");
    var map;

    var arrayInformation = [];

    window.facebookUserInformation = {
        name: "",
        picture: ""
    };

    window.userInformation = [{

    }];

    buttonCreate.onclick = function() { // When create is clicked on, under the display view, show a blank text input and a button.
        inputName.style.display = "inline-block";
        inputTitle.style.display = "inline-block";
        inputImage.style.display = "inline-block";
        inputStatus.style.display = "inline-block";
        inputLatitude.style.display = "inline-block";
        inputLongitude.style.display = "inline-block";
        storeInformation.style.display = "inline-block";
    };

    storeInformation.onclick = function() { // When the button is clicked on, push the value into an array.
        var objectInformation = {
            _name: inputName.value,
            _title: inputTitle.value,
            _image: "<img src='" + inputImage.value + "'/>",
            _status: inputStatus.value,
            _latitude: inputLatitude.value,
            _longitude: inputLongitude.value
        };
        arrayInformation.push(objectInformation);
        inputImage.value = "";
        inputName.value = "";
        inputTitle.value = "";
        inputStatus.value = "";
        inputLatitude.value = "";
        inputLongitude.value = "";
    };

    function viewInformation(number) { // When view is clicked on, loop through the array and display all the items. Beside each item are an edit button and a delete button.
        var informationDiv = document.createElement("div");
        displayInformation.appendChild(informationDiv);
        informationDiv.innerHTML = arrayInformation[number]._image + " " + arrayInformation[number]._name + " " + arrayInformation[number]._title + " " + arrayInformation[number]._status;

        // Beside each item are an edit button and a delete button.
        var buttonEdit = document.createElement("button");
        buttonEdit.type = "button";
        buttonEdit.setAttribute("class", "btn btn-default");
        buttonEdit.innerHTML = "Edit";
        buttonEdit.dataset.indexValue = number;
        informationDiv.appendChild(buttonEdit);

        var buttonDelete = document.createElement("button");
        buttonDelete.type = "button";
        buttonDelete.setAttribute("class", "btn btn-default");
        buttonDelete.innerHTML = "Delete";
        buttonDelete.dataset.indexValue = number;
        informationDiv.appendChild(buttonDelete);

        buttonDelete.onclick = function() { // When delete is clicked on, remove the item from the array.
            var buttonDeleteIndex = this.dataset.indexValue;
            arrayInformation.splice(buttonDeleteIndex, 1);
            displayInformation.innerHTML = "";
            for (var i = 0; i < arrayInformation.length; i++) {
                viewInformation(i);
            }
        };

        buttonEdit.onclick = function() {
            var buttonEditIndex = this.dataset.indexValue;
            displayInformation.innerHTML = "";
            arrayInformation[buttonEditIndex] = {
                _image: arrayInformation[buttonEditIndex]._image,
                _name: "<input value='" + arrayInformation[buttonEditIndex]._name + "'/>",
                _title: "<input value='" + arrayInformation[buttonEditIndex]._title + "'/>",
                _status: "<input value='" + arrayInformation[buttonEditIndex]._status + "'/>"
            };
            for (var i = 0; i < arrayInformation.length; i++) {
                viewInformation(i);
            }
        };
    }

    buttonView.onclick = function() {
        displayInformation.innerHTML = "";
        for (var i = 0; i < arrayInformation.length; i++) {
            viewInformation(i);
        }
        initMap();
    };

    // Facebook
    window.fbAsyncInit = function() {

        FB.init({appId: '173223693137232', xfbml: true, version: 'v2.8'});

        $("#buttonFacebookLogin").click(function() {
            $(this).hide();
            $("#buttonCreate").show();
            $("#buttonView").show();
            FB.login(function(response) {
                if (response.status == 'connected') {
                    FB.api("/me?fields=name,picture", function(userResponse) {
                        window.facebookUserInformation.name = userResponse.name;
                        window.facebookUserInformation.picture = userResponse.picture.data.url;
                        inputName.value = window.facebookUserInformation.name;
                        inputImage.value = window.facebookUserInformation.picture;
                    });
                } else {
                    return false;
                }
            });
        });
    };

    (function(d, s, id) {
        var js,
            fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) {
            return;
        }
        js = d.createElement(s);
        js.id = id;
        js.src = "//connect.facebook.net/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

    // Google Maps
    function initMap() {
        map = new google.maps.Map(document.getElementById("map"), {
            center: {
                lat: parseInt(arrayInformation[(arrayInformation.length - 1)]._latitude),
                lng: parseInt(arrayInformation[(arrayInformation.length - 1)]._longitude)
            },
            zoom: 5
        });
        for (var i = 0; i < arrayInformation.length; i++) {
            var marker = new google.maps.Marker({
                position: {
                    lat: parseInt(arrayInformation[i]._latitude),
                    lng: parseInt(arrayInformation[i]._longitude)
                },
                map: map
            });
        }
    }

});

用于上下文的HTML:

<!DOCTYPE html>

<html>

<head>
    <title>Control Panel</title>
    <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
    <link rel='stylesheet' href='css/style.css'>
</head>

<body>

    <div class='flex-container'>

        <div class='flex-item'>
            <div class='container'>
                <div class='well well-lg'>
                    <div class='btn-group' role='group'>
                        <button id='buttonFacebookLogin' type='button' class='btn btn-default'>Login with Facebook</button>
                        <button id='buttonCreate' type='button' class='btn btn-default'>Create</button>
                        <button id='buttonView' type='button' class='btn btn-default'>View</button>
                    </div>
                    <div class='input-group'>
                        <input id='inputImage' type='text' class='form-control' placeholder='Image'>
                        <input id='inputName' type='text' class='form-control' placeholder='Name'>
                        <input id='inputTitle' type='text' class='form-control' placeholder='Title'>
                        <input id='inputStatus' type='text' class='form-control' placeholder='Status'>
                        <input id='inputLatitude' type='number' min='-85' max='85' class='form-control' placeholder='Latitude'>
                        <input id='inputLongitude' type='number' min='180' max='180' class='form-control' placeholder='Longitude'>
                        <span class='input-group-btn'>
                          <button id='storeInformation' class='btn btn-default' type='button'>Store Information</button>
                        </span>
                    </div>
                </div>
            </div>
        </div>

        <div class='flex-item'>
            <div class='container'>
                <div id='displayInformation' class='well well-lg'></div>
                <div id='displayReact' class='well well-lg'></div>
                <div id='map'></div>
            </div>
        </div>

    </div>

    <!-- Scripts -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src='https://maps.googleapis.com/maps/api/js?key=AIzaSyAGZd9Y2YB7omGFkeeS0Y6QQOi8pXAs3Ag'></script>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.js"></script>
    <script src='js/script.js'></script>
    <script src="js/babel.js" type="text/babel"></script>
</body>

</html>

1 个答案:

答案 0 :(得分:0)

按钮没有显示,因为self.props.list未定义。您应该使用默认道具https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values或写:

(self.props.list || []).map(function...

(默认道具更优雅)