尝试显示数据时显示未捕获错误的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
?>
答
- 您引用的函数,
displayRecords
,是不是在页面的全球范围内,它的componentDidMount
中定义的,这是不提供给你的HTML标签。 -
select
标记在label
标记内无效。 - 您正在使用HTML和React,为什么?
- 您在未绑定函数内绑定
this
,其中this
解析为根作用域,这就是为什么setState
未定义的原因。 - 你正在设置一个标签的内部HTML使用jQuery,而不是反应...为什么?
- 您正在使用
dangerouslySetInnerHTML
,您不应该,有更好的方法。 - 您正在从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
凯尔,你真是太好了。你的第一个直接的固定代码非常棒。它解决了上面列出的错误问题2和3。但我仍然只有这个错误1问题。 “未捕获的类型错误:无法在渲染属性中读取未定义的属性”setState“。结果应该显示reactjs“dangerouslySetInnerHTML = {{__ html:this.state.data}}”而不是“$('#display')。html(data).show();”..对不起混乱。您可以从Web控制台查看错误。请这只是最后的要求。感谢您的及时努力。我仍然依靠你。 – bowman87
@ bowman87请参阅最新的代码...另外,我强烈建议您重新编写代码,使其更像我的第二个示例。目前你正在做一些非常奇怪的事情,这些事情没有道理,违反标准。另外,我建议你阅读这篇文章:https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/ – Kyle
凯尔你好,它不显示任何东西。它仍然显示错误。 “未捕获的类型错误:无法在渲染属性中读取未定义的属性”setState“。其解决了 – bowman87