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

问题描述:

我正尝试从头开始编写reactjs分页代码,但遇到以下错误,我一直在困难中。尝试显示数据时显示未捕获错误的Reactjs

1)Reactjs试图从数据库中显示的记录 时显示以下错误“遗漏的类型错误:未定义无法读取属性‘的setState’”

2)当我点击网页链接,它“Uncaught 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. 您引用的函数,displayRecords,是不是在页面的全球范围内,它的componentDidMount中定义的,这是不提供给你的HTML标签。
  2. select标记在label标记内无效。
  3. 您正在使用HTML和React,为什么?
  4. 您在未绑定函数内绑定this,其中this解析为根作用域,这就是为什么setState未定义的原因。
  5. 你正在设置一个标签的内部HTML使用jQuery,而不是反应...为什么?
  6. 您正在使用dangerouslySetInnerHTML,您不应该,有更好的方法。
  7. 您正在从React组件中调用$(document).ready ...如果组件已安装,则此文档已准备就绪,这是不需要的逻辑。

这里是你的问题的直接修复:

<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

+0

凯尔,你真是太好了。你的第一个直接的固定代码非常棒。它解决了上面列出的错误问题2和3。但我仍然只有这个错误1问题。 “未捕获的类型错误:无法在渲染属性中读取未定义的属性”setState“。结果应该显示reactjs“dangerouslySetInnerHTML = {{__ html:this.state.data}}”而不是“$('#display')。html(data).show();”..对不起混乱。您可以从Web控制台查看错误。请这只是最后的要求。感谢您的及时努力。我仍然依靠你。 – bowman87

+0

@ bowman87请参阅最新的代码...另外,我强烈建议您重新编写代码,使其更像我的第二个示例。目前你正在做一些非常奇怪的事情,这些事情没有道理,违反标准。另外,我建议你阅读这篇文章:https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/ – Kyle

+0

凯尔你好,它不显示任何东西。它仍然显示错误。 “未捕获的类型错误:无法在渲染属性中读取未定义的属性”setState“。其解决了 – bowman87