我试图构建一个小型React.js应用程序,我的组件结构如下所示:
MainComponent
- CategoryList
-Category
- ItemsList
-Item
我的MainContent组件在componentDidRender:
中对其状态数据执行ajax请求,该请求返回以下对象:
data:[
Object[0]
-name
-items[]
,
Object[1],
Object[2]
]
现在,我想让我的CategoryList按名称写出所有的Categories,这很好,但我还想打印出所选类别的项目。
var ItemsList = React.createClass({
render:function(){
var itemNodes = this.props.category.items.map(function(item){
return (
<Item name={item.name} />
);
});
return(
<div className="itemList">
{itemNodes}
</div>
);
}
});
这就是我从父组件传递"category"属性的方法
<ItemsList category={this.state.data[0]} />
我收到一个错误,说"无法读取未定义的属性项",这意味着类别prop从未被分配。我知道www.example.com包含一个对象数组,所以我在这里没有看到这个错误。this.state.data contains an array of objects so I don´t see the error here.
我做错了什么?
编辑:根据请求,这是我的主要组件:
var MainComponent = React.createClass({
getInitialState:function(){
return {data: []};
},
componentDidMount:function(){
$.ajax({
type:'get',
url: '/categories',
dataType: 'json',
success:function(data){
this.setState({data: data});
}.bind(this)
});
},
render: function(){
return (
<div className="row">
<div className="col-md-6">
<CategoryList categories={this.state.data} />
</div>
<div className="col-md-6">
<ItemsList category={this.state.data[0]} />
</div>
</div>
);
}
});
2条答案
按热度按时间vojdkbi01#
Modern(2023)React告诉你要使用函数组件,所以,如果你想从服务器上传数据并在组件中呈现它,你需要使用所谓的“钩子”,名为“useEffect”和“useState”。
因此,首先导入它们:
接下来,创建一个功能组件并初始化组件中的'state'和'set_state function':
这将创建“value”变量,该变量将在渲染过程中保持其状态。
然后,您发出一个获取请求(在组件的return语句之前)(但您需要将其放在useEffect函数中以获得一致的行为):
现在,你明白为什么我们需要状态了:因为我们需要将从服务器返回的数据存储在一个变量中,并且我们需要这些数据在渲染中保留。另外,您认为现在可以在组件的返回渲染中使用数据,如下所示:
但是你会遇到“阅读未定义”的错误。
首先,检查服务器返回的对象类型是否正确,在fetch请求中放入console.log语句:
它应该是一个包含对象的列表,例如:[{}、{}、{}]。
如果是,那么问题是组件在从服务器接收数据之前呈现。组件将首先呈现,然后从服务器接收数据。如果在render语句中调用state变量,它将调用空状态。
因此,为了缓解这种情况,您的代码应该准备好呈现空状态和带有数据的状态。最简单的方法是条件呈现。仅当有数据要呈现时,才呈现带有数据的组件:
'value &&'部分允许您实现以下逻辑:
为什么会这样呢?“&&”的表达方式(a和B)从右向左求值。如果第一个变量求值为“false”,则它不再继续并停止在此。变量“value”的初始状态是空对象('let [ value,set_value ] = useState([])' -还记得吗?).因此,当服务器在第一次呈现时还没有返回数据时,表达式“value &&”的计算结果为“false”并且不呈现表达式的右侧部分。当服务器返回数据时,它使用数据调用“setState”函数,并强制第二次呈现组件。第二次表达式“value &&”的计算结果为“true”React会转到表达式的右边部分,实际上呈现了包含数据的组件。您可以通过将console.log语句放在fetch请求和return语句中来检查此过程,您将看到函数解析的顺序。
希望能有所帮助。另外,请查看这篇文章:https://daveceddia.com/react-before-render/
快乐编码〉〉
x4shl7ld2#
主组件在
data
中用一个空数组初始化状态,因为没有this.state.data[0]
,所以渲染总是失败。人们可能会回答说 AJAX 请求将提供这个状态属性
data
的值(假设你的web服务提供了一个有效的数组)。然而,这只发生在从服务器接收到响应之后,而在第一次呈现之后不会发生。如果信息立即可用,则可以在方法
componentWillMount
或组件构造函数上使用setState
,以避免触发第二次渲染:componentWillMount()在装载发生前立即调用。它在render()之前调用,因此在此方法中同步设置状态不会触发重新呈现。避免在此方法中引入任何副作用或订阅。
在这种情况下,由于我们正在等待远程信息,React文档仍然建议使用
componentDidMount
,这里也使用了componentDidMount
:在装入组件后立即调用componentDidMount()。需要DOM节点的初始化应在此处进行。如果需要从远程终结点加载数据,则这是示例化网络请求的好位置。在此方法中设置状态将触发重新呈现。
因此,组件的render方法必须能够处理丢失的状态变量。有多种方法可以解决这个问题,但是在我们得到
data
之前阻止嵌套元素被呈现是最简单的方法。通过一些额外的逻辑,应用程序可以通知用户特定的组件正在加载。