2017-10-07 105 views
-2

我正嘗試從頭開始編寫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 
?> 

回答

0
  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