Реагирование на извлечение данных не работает

#javascript #php #html #reactjs

#javascript #php #HTML #reactjs

Вопрос:

Я новичок в react и пытаюсь создать компонент таблицы, который изменяется в зависимости от того, что передается для заголовков и строк.

Я следил за учебными пособиями fb react, и я столкнулся с препятствием, которое я просмотрел здесь, и внес некоторые изменения, но ничего не работает.

Вот моя HTML-страница, которая получает сгенерированный контент.

 <!DOCTYPE html>
<html lang="en-us">
    <head>
        <meta charset='utf-8'>
        <meta http-equiv="X-UA-Compatible" content="IE=10; IE=9; IE=8; IE=7; IE=EDGE" />
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- CSS -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.4.1/css/bootstrap-datepicker3.css"/>
        <link rel="stylesheet" type="text/css" href="/vendor/twbs/bootstrap/dist/css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="/vendor/etdsolutions/sweetalert/sweetalert.css?<?= assetCacheQueryStr() ?>" />
        <link rel="stylesheet" type="text/css" href="/lib/jquery-ui-1.11.4/jquery-ui.css">
        <link rel="stylesheet" type="text/css" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.3/css/bootstrap-select.min.css">

        <!-- Javascript -->
        <script src="https://unpkg.com/react@15.3.2/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.3.2/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
    <script src="https://unpkg.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/remarkable@1.6.2/dist/remarkable.min.js"></script>
        <script src="/vendor/etdsolutions/sweetalert/sweetalert.min.js?<?= assetCacheQueryStr()?>"></script>
    <script src="/vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.3/js/bootstrap-select.min.js"></script>
        <script src="/lib/sorttable.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.4.1/js/bootstrap-datepicker.min.js"></script>

    <title>React</title>
  </head>
    <body>
        <div id="loadboardContainer"></div>

        <!-- Import the table react setup. -->
        <script type="text/babel" src="test.js"></script>
    </body>
</html>
  

Теперь у меня есть внешний скрипт react в test.js файл, который является этим.

 var Table = React.createClass({
  getInitialState: function() {
    return {
      results: [],
      columns: []
    }
  },
  componentDidMount: function() {
    this.serverRequest = $.get(this.props.source, function(result) {
      result = JSON.parse(result);
      this.setState({
        results: result['resultRows'],
        columns: $.makeArray(result['resultCols'])
      });
    }.bind(this));
  },
  componentWillUnmount: function(){
    this.serverRequest.abort();
  },
  render: function() {
    // Set array for rows.
    var rows = [];
    var header = [];

    this.state.columns.map(function(cols) {
      header.push(<TableColumns data={cols.cols} key={cols.id} />);
    });

    this.state.results.map(function(result) {
      rows.push(<TableRow data={result.rows} key={result.id} />);
    });

    // Loop through head to get columns.
    /*this.props.columns.forEach(function(cols) {
      header.push(<TableColumns data={cols.cols} key={cols.id} />);
    });

    // Loop through the returned rows and display.
    this.props.results.forEach(function(result) {
      rows.push(<TableRow data={result.rows} key={result.id} />);
    });*/


    // Return the table.
    return (
      <table className="table table-condensed">
        <thead>
          {header}
        </thead>
        <tbody>
          {rows}
        </tbody>
      </table>
    );
  }
});

// Set up columns
var TableColumns = React.createClass({
  render: function() {
    var colNodes = this.props.data.map(function(col, i){
      return (
        <th key={i}>{col}</th>
      );
    });
    return (
      <tr>
        {colNodes}
      </tr>
    );
  }
});

// Set up row
var TableRow = React.createClass({
  render: function() {
    var rowNodes = this.props.data.map(function(row, i){
      return (
        <td key={i}>{row}</td>
      );
    });
    return (
      <tr>
        {rowNodes}
      </tr>
    );
  }
});

var futureContainer = document.getElementById('loadboardContainer');

ReactDOM.render(<Table source="getTableValues.php" />, futureContainer);
  

Как вы можете видеть, у меня есть закомментированная часть того, что раньше было вызовами props для таблицы. Теперь, когда я пытаюсь получить информацию из другого файла, похоже, что здесь я должен использовать state.

В другом файле это то, что у меня есть. Это просто массив массива для возврата данных, прежде чем я действительно запрошу материал.

 <?php
  // Start the session.
  session_start();

  // Set Variables.
  $returned = array(); // Returns results

  $returned['resultRows'][0] = array();
  $returned['resultRows'][0]['id'] = 10221;
  $returned['resultRows'][0]['rows'] = array("654221", "2016-03-26", "Customer 1", "98755/54622", "Carrier 1", "Driver 1", "2016-03-28", "TX - IN", "DRY", "1240", "", "", "This is a test note");

  $returned['resultRows'][1] = array();
  $returned['resultRows'][1]['id'] = 10223;
  $returned['resultRows'][1]['rows'] = array("654221", "2016-03-26", "Customer 1", "98755/54622", "Carrier 2", "Driver 2", "2016-03-28", "TX - IN", "DRY", "1240", "", "", "This is a test note2");

  $returned['resultCols']['id'] = 100;
  $returned['resultCols']['cols'] = array("PO Number", "Load Date", "Customer(s)", "Customer PO", "Carrier", "Driver", "Delivery Date", "Lane", "Temp", "Weight", "Attention Date", "ND Date", "Notes");

  echo json_encode($returned);
?>
  

Я продолжаю получать сообщение об ошибке this.state.columns.map не является функцией.
То же самое верно, если я использую this.props. Итак, что я делаю не так в этом? Я знаю, как заставить это работать, если я статически вставляю данные и вставляю их таким образом на страницу since, но вызов не работает.

Комментарии:

1. Вы должны проверить, что this.state.columns это не определено, прежде чем пытаться сопоставить его.

2. Разве оно не должно всегда определяться с момента его установки в getInitialState? Если я предупреждаю об этом, он ничего не показывает, только пустое поле, но то, как в их документации говорится, кажется, что оно определено так долго, и оно определено в getInitialState.

3. Не используйте оповещения для тестирования кода, так как это может привести к блокировке, попробуйте console.log вместо этого. у вас там были строки до того, как вы их изменили (у которых нет map в их прототипе).

Ответ №1:

Вы пытаетесь сопоставить строку в начале из-за async $.get

замените это :

 getInitialState: function() {
  return {
     results: '',
     columns: ''
  }
}
  

этим :

 getInitialState: function() {
  return {
     results: [],
     columns: []
  }
}
  

ОТРЕДАКТИРУЙТЕ, ЧТОБЫ СООТВЕТСТВОВАТЬ ВОЗВРАЩЕНИЮ PHP

 var Table = React.createClass({
  getInitialState: function() {
    return {
      results: [],
      columns: []
    }
  },
  componentDidMount: function() {
    this.serverRequest = $.get(this.props.source, function(result) {
      result = JSON.parse(result);
      this.setState({
        results: result['resultRows'],
        columns: result['resultCols'].cols
      });
    }.bind(this));
  },
  componentWillUnmount: function(){
    this.serverRequest.abort();
  },
  render: function() {    

    // Return the table.
    return (
      <table className="table table-condensed">
        <thead>
          <TableColumns data={this.state.columns} />
        </thead>
        <tbody>
          {this.state.results.map(function(result) {
            rows.push(<TableRow data={result.rows} key={result.id} />);
          })}
        </tbody>
      </table>
    );
  }
});

// Set up columns
var TableColumns = React.createClass({
  render: function() {
    var colNodes = this.props.data.map(function(col, i){
      return (
        <th key={i}>{col}</th>
      );
    });
    return (
      <tr>
        {colNodes}
      </tr>
    );
  }
});

// Set up row
var TableRow = React.createClass({
  render: function() {
    var rowNodes = this.props.data.map(function(row, i){
      return (
        <td key={i}>{row}</td>
      );
    });
    return (
      <tr>
        {rowNodes}
      </tr>
    );
  }
});

var futureContainer = document.getElementById('loadboardContainer');

ReactDOM.render(<Table source="getTableValues.php" />, futureContainer);
  

Комментарии:

1. Значит, react не переопределяет переменные? Я изменил его, теперь он говорит, что состояние не определено.

2. React переопределит переменные, но после выполнения вашего запроса. Поэтому, прежде чем он попытается сопоставить строку. Но почему это состояние не определено? … не могли бы вы записать результаты (в $.get), а затем состояние (в render() )?

3. {«Resultrow»:[{«id»:10221, «строки»:[«654221″,»2016-03-26″,» Клиент 1″,»98755/54622″,» Перевозчик 1″, «Водитель 1», «2016-03-28», «TX — IN», «СУХОЙ»,»1240″,»»,»»,» Это тестовая заметка»]},{«id»:10223,»строки»:[«654221″,»2016-03-26″,» Клиент 1″,»98755/54622″,» Держатель 2″,»Драйвер 2″,»2016-03-28″,»TX — IN», «DRY»,»1240″,»»,»»,» Это тест note2″]}],»resultCols»:{«id»:100,»cols»:[«Номер ПО»,»Дата загрузки», «Клиент (ы)», «Клиентская почта», «Перевозчик», «Водитель», «Дата доставки», «Полоса движения», «Температура», «Вес», «Дата внимания», «Дата ND»,»Примечания»]}}

4. Я не могу поверить, что this.state это не определено… это действительно странно …

5. Да, я просто ввел json.parse, и он возвращает объекты так, как я и думал, но после этого он дает мне понять, что this.state.columns.map не является функцией