我有这个React组件
import React, { Component } from "react";
export default class ResourceForField extends Component {
constructor() {
super();
this.state = {
resources: [],
};
}
componentDidMount() {
// get the resources from the Link props and save it into the state
this.setState({
resources: this.props.location.resources,
});
}
// This component gets the id of current learningField from the url
// and the rest(like the resources) from the Link component
render() {
return (
<div>
{this.state.resources.map(res => (
<div>test</div>
))}
</div>
);
}
}
它从Link组件获取资源,并且工作正常。如果我从开发工具中检查Component的状态,则状态看起来正确。我以我的逻辑认为这应该可行。因此,首先,状态为空,将渲染组件,因为状态为空,因此不渲染任何组件。然后,调用setState,它获取所有资源并将其保存到状态中,然后该组件将重新呈现,并且它应该可以工作,但不能。我收到一个TypeError: Cannot read property 'map' of undefined
错误。正确的方法是什么?如何解决?
答案 0 :(得分:2)
尝试此代码:
import React, { Component } from "react";
export default class ResourceForField extends Component {
constructor() {
super();
this.state = {
resources: this.props && this.props.location && this.props.location.resources?this.props.location.resources:[],
};
}
componentDidMount() {
}
// This component gets the id of current learningField from the url
// and the rest(like the resources) from the Link component
render() {
return (
<div>
{this.state.resources.map(res => (
<div>test</div>
))}
</div>
);
}
}
或直接使用道具
import React, { Component } from "react";
export default class ResourceForField extends Component {
constructor() {
super();
}
// This component gets the id of current learningField from the url
// and the rest(like the resources) from the Link component
render() {
return (
<div>
{
this.props && this.props.location &&
this.props.location.resources
?this.props.location.resources.map(res => (
<div>test</div>
))
:null
}
</div>
);
}
}
或使用componentWillReceiveProps
或getDerivedStateFromProps
生命周期方法。
检查this.props.location.resources
是否为array
。
查看更多:https://hackernoon.com/replacing-componentwillreceiveprops-with-getderivedstatefromprops-c3956f7ce607
答案 1 :(得分:0)
对于第一个检查是<table id="mainTable" class=" table table-striped table-bordered text-center">
<thead>
<tr>
<th></th>
<th>Year 1</th>
<th>Year 2</th>
<th>Year 3</th>
<th>Year 4</th>
<th>Year 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Retail Price</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
</tr>
<tr>
<td>Retail Quantity</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
</tr>
<tr>
<td>Affiliate Price</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
</tr>
<tr>
<td>Affiliate Quantity</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
</tr>
<tr>
<td>Whole Prize</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
</tr>
<tr>
<td>Whole Quantity</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
</tr>
<tr>
<td>Custom Prize</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
</tr>
<tr>
<td>Custom Quantity</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
<td>10</td>
</tr>
<tr>
<td>Unit Cost</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
<td>1780</td>
</tr>
</tbody>
<tfoot>
<tr>
<th><strong>TOTAL</strong></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#mainTable').editableTableWidget()
});
</script>
数组,或者如果可以更改数据类型可以添加检查,则可以使用lodash this.props.location.resources
或与js一起使用:
isArray
或者您也可以像这样使用hooks:
import React, { Component } from "react";
export default class ResourceForField extends Component {
constructor() {
super();
this.state = {
resources: [],
};
}
componentDidMount() {
// get the resources from the Link props and save it into the state
Array.isArray(this.props.location.resources) {
this.setState({
resources: this.props.location.resources,
});
}
}
// This component gets the id of current learningField from the url
// and the rest(like the resources) from the Link component
render() {
return (
<div>
{this.state.resources.map(res => (
<div>test</div>
))}
</div>
);
}
}
答案 2 :(得分:0)
如果ResourceForField
的内部状态没有改变并且始终等于其prop,则不应将prop保存在该状态中。您可以创建一个纯功能组件。
还要注意,没有什么可以阻止您从构造方法中的props初始化状态。也就是说,您无需等待组件安装即可访问道具。
因此,我将为ResourceForField
编写以下组件:
function ResourceForField({resources = []}) {
return (
<div>
{
resources.map(res => (<div>test</div>))
}
</div>
);
}