简体   繁体   English

反应有时不渲染按钮?

[英]React sometimes does not render button?

I'm just starting to learn React and how to integrate it with different APIs. 我才刚刚开始学习React以及如何将其与不同的API集成在一起。 What my page does right now is it grabs information from input fields and React should render it in a view section. 我的页面现在要做的是它从输入字段中获取信息,React应该在视图部分中呈现它。 However, sometimes (if I keep refreshing) the button that React is supposed to render doesn't show up and returns the error: 但是,有时(如果我不断刷新)React应该渲染的按钮没有显示并返回错误:

Uncaught TypeError: Cannot read property 'map' of undefined

Also, I inspected the HTML and there's one empty div before all the divs for the user's information. 另外,我检查了HTML,在所有div之前有一个空的div供用户参考。 What I'm trying to achieve so far works but only if the "Add Information" button decides to show up. 到目前为止,我要实现的目标是可行的,但前提是“添加信息”按钮决定显示。

I uploaded it here if it helps to visualize my problem: testing.nicholasdrzewiecki.ca - if you keep refreshing sometimes the "Add Information" button doesn't appear. 如果可以帮助可视化我的问题,我将其上传到此处:testing.nicholasdrzewiecki.ca-如果您不断刷新,有时“添加信息”按钮不会出现。 The Facebook login isn't set up but click it to show the create button which makes the inputs, fill the inputs with random info and click "Add Information". 没有设置Facebook登录名,但单击它以显示创建输入的创建按钮,用随机信息填充输入,然后单击“添加信息”。

My babel code looks like this: 我的babel代码如下所示:

// 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")
);

And my other JavaScript file with the Facebook and Google Maps API looks like this: 我的另一个带有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
            });
        }
    }

});

And HTML for context: 和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>

Button doesn't show because self.props.list is undefined. 按钮未显示,因为self.props.list未定义。 You should use default props https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values or write: 您应该使用默认道具https://facebook.github.io/react/docs/typechecking-with-proptypes.html#default-prop-values或写:

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

(Default props are more elegant) (默认道具更优雅)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM