尝试显示数据时,Reactjs显示未捕获的错误

时间:2017-10-07 18:37:47

标签: javascript reactjs

我试图从头开始编写reactjs分页,但是我遇到了以下错误。

1。)尝试显示数据库中的记录时,Reactjs显示以下错误  “未捕获的TypeError:无法读取未定义的属性'setState'”

2.。)当我点击页面链接时,它显示“未捕获的ReferenceError:未定义displayRecords     在HTMLAnchorElement.onclick“。似乎 displayRecords()函数在下面的javascript中没有很好地定义或绑定。

3。)当我点击下拉链接时,它显示“未捕获的ReferenceError:未定义changeDisplayRowCount     在HTMLSelectElement.onchange“。似乎 changeDisplayRowCount()函数在下面的javascript中没有很好地定义或绑定。

请有人运行该脚本并帮我解决问题。至少即使它只是第一个错误(“Uncaught TypeError:无法读取未定义的属性'setState'”)。

<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<script src="build/jquery.min.js"></script>


<a href="javascript:void(0);" class="links"  onclick="displayRecords('10', '1');" >Page</a>
<label> Rows Limit: 
<select name="show" onChange="changeDisplayRowCount(this.value);">
  <option value="10" >10</option>
  <option value="20" >20</option>
  <option value="30" >30</option>
</select>
</label>
<div id="root"></div>
<script type="text/babel">

class NameForm extends React.Component {
  constructor() {
    super();
    this.state = {
      data: []
    };
  }
  componentDidMount() {
    function displayRecords(numRecords, pageNum) {
      var show = numRecords;
      var pagenum = pageNum;

      alert(show);

      $.ajax({
        type: 'GET',
        url: 'getrecords.php',
        data: {
          show: numRecords,
          pagenum: pageNum
        },
        cache: false,
        success: function(data) {
          show: numRecords;
          pagenum: pagenum;

          $('#display')
            .html(data)
            .show();

          //console.log(email);

          console.log(show);
          console.log(pagenum);

          this.setState({data: data});
        }.bind(this),
        error: function(jqXHR) {
          console.log(jqXHR);
        }.bind(this)
      });
    } // end displayRecords

    function changeDisplayRowCount(numRecords) {
      displayRecords(numRecords, 1);
    }

    $(document).ready(function() {
      displayRecords(10, 1);
    });
  }

  render() {
    return (
      <div>
        {this.state.data ? (
          <div dangerouslySetInnerHTML={{__html: this.state.data}} />
        ) : (
          <div>Loading...</div>
        )}
      </div>
    );
  }
}
ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);


</script>

getrecords.php

<?php

echo $page = $_GET['pagenum'];
echo $show = $_GET["show"];

// pagination
?>

1 个答案:

答案 0 :(得分:1)

  1. 您正在引用一个不在页面全局范围内的displayRecords函数,它在componentDidMount内定义,而HTML标记无法使用该函数。
  2. select标记在label标记内无效。
  3. 你正在使用HTML和React,为什么?
  4. 您在未绑定的函数中绑定this,其中this已解析为根范围,这就是未定义setState的原因。
  5. 您正在使用jquery设置标记的内部HTML,而不是反应......为什么?
  6. 你正在使用dangerouslySetInnerHTML,你应该没有,有更好的方法。
  7. 您正在React组件中调用$(document).ready ...如果组件已安装,则文档已准备就绪,这是不需要的逻辑。
  8. 以下是您问题的直接解决方法:

    <script src="build/react.min.js"></script>
    <script src="build/react-dom.min.js"></script>
    <script src="build/browser.min.js"></script>
    <script src="build/jquery.min.js"></script>
    
    
    <a href="javascript:void(0);" class="links"  onclick="displayRecords('10', '1');" >Page</a>
    <label> Rows Limit: 
    <select name="show" onChange="changeDisplayRowCount(this.value);">
      <option value="10" >10</option>
      <option value="20" >20</option>
      <option value="30" >30</option>
    </select>
    </label>
    <div id="root"></div>
    <script type="text/babel">
    window.displayRecords = function(){
        alert('Component not mounted yet.');
    };
    
    window.changeDisplayRowCount = function(){
        alert('Component not mounted yet.');
    }
    class NameForm extends React.Component {
      constructor() {
        super();
        this.state = {
          data: []
        };
      }
      componentDidMount() {
        window.displayRecords = (function displayRecords(numRecords, pageNum) {
          var show = numRecords;
          var pagenum = pageNum;
    
          alert(show);
    
          $.ajax({
            type: 'GET',
            url: 'getrecords.php',
            data: {
              show: numRecords,
              pagenum: pageNum
            },
            cache: false,
            success: function(data) {
              show: numRecords;
              pagenum: pagenum;
    
              $('#display')
                .html(data)
                .show();
    
              //console.log(email);
    
              console.log(show);
              console.log(pagenum);
    
              this.setState({data: data});
            }.bind(this),
            error: function(jqXHR) {
              console.log(jqXHR);
            }.bind(this)
          });
        }.bind(this) // end displayRecords
    
        window.changeDisplayRowCount = function changeDisplayRowCount(numRecords) {
          displayRecords(numRecords, 1);
        }
    
        $(document).ready(function() {
          displayRecords(10, 1);
        });
      }
    
      render() {
        return (
          <div>
            {this.state.data ? (
              <div dangerouslySetInnerHTML={{__html: this.state.data}} />
            ) : (
              <div>Loading...</div>
            )}
          </div>
        );
      }
    }
    ReactDOM.render(
      <NameForm />,
      document.getElementById('root')
    );
    
    
    </script>
    

    虽然这可以解决您的问题(或者可能应该这样),但以下是您的代码应该的内容:

    function PageLink({page,onClick}){
      return <div className="pageLink" onClick={onClick.bind(null,page)}>
        {page}
      </div>;
    }
    
    function RowSelector({selected,onChange}){
      return (
        <div className="rowSelector">
          <label>Rows Limit:</label>
          <select onChange={(e) => onChange(e.target.value)} value={selected}>
              {[10,20,30].map(num => <option key={num} value={num}>{num}</option>)}
          </select>
        </div>
      )
    }
    
    function DataItem({item}){
      // Assumes data is a map with a name key.
      return <div>{item.name}</div>;
    }
    
    class Pagination extends React.Component {
      constructor(props){
        super(props);
        this.state = {
          currentPage: 0,
          rowLimit: 10,
          data: [],
          loading: false
        };
        this.setCurrentPage = this.setCurrentPage.bind(this);
        this.setRowLimit = this.setRowLimit.bind(this);
      }
    
      updateData(){
        this.setState({loading: true});
        // This is just for mock purposes, remove this and use the ajax logic below.
        setTimeout(() => {
          this.setState({
            loading: false,
            data: (function(rowLimit){
              let res = [];
              for(let i = 0; i < rowLimit; i++){
                res.push({name: String(i)});
              }
              return res;
            })(this.state.rowLimit)
          })
        },1000);
        return;
        $.ajax({
          type: 'GET',
          url: 'getrecords.php',
          data: {
            show: this.state.rowLimit,
            pagenum: this.state.currentPage
          },
          cache: false,
          success: data =>  this.setState({data,loading: false}),
          error: jqXHR => {
            this.setState({loading:false});
            console.log(jqXHR);
          }
        });
      }
    
      componentDidUpdate(prevProps,prevState){
        if(this.state.currentPage != prevState.currentPage || this.state.rowLimit != prevState.rowLimit){
          this.updateData();
        }
      }
    
      componentDidMount(){
        this.updateData();
      }
    
      setCurrentPage(currentPage){
        this.setState({currentPage});
      }
    
      setRowLimit(rowLimit){
        this.setState({rowLimit})
      }
    
      renderLoading(){
        return <div>Loading ...</div>;
      }
    
      renderData(){
        return <div>
          {this.state.data.map(
             (item,key) => <DataItem item={item} key={key}/>
          )}
        </div>
      }
    
        render(){
            return (
          <div>
            <PageLink page={1} onClick={this.setCurrentPage}/>
            <RowSelector onChange={this.setRowLimit} selected={this.rowLimit}/>
            {this.state.loading ? this.renderLoading() : this.renderData()}
          </div>
        );
        }
    }
    
    ReactDOM.render(
      <Pagination />,
      document.getElementById('react')
    );
    

    你可以在这里看到这个:https://codepen.io/anon/pen/qPoBjN