将获取的数据作为 props (a JSON) 传递给 state 以呈现数据
Pasing fetched data as props (a JSON) to state in order to render data
目前,当 运行 完成我的 saga 时,我从 API 中以 JSON 格式获取数据。当组件挂载时,抓取过程开始。这意味着组件渲染了两次。
现在,当数据作为道具可用时。我可以使用它来渲染它。
我的方法如下,我有一个:
- 具有初始状态的构造函数
- 我在"componentDidMount"
中获取数据
- 我得到了一个函数,它从 props 中获取 JSON 属性并将其放入新变量中
- 我在我的 render() 函数中 运行 这个函数,当 props 包含获取的数据时
此方法中的问题:一旦组件 运行 成为数据变为 "structured" 的函数,渲染函数就会循环,然后有时,属性的值会在控制台中显示一条警告消息。
我的问题:
- render() 运行一次时如何防止循环?
- 我如何设计它,以便将获取的对象的特定属性合并到一个新对象中以及如何
我希望我描述了关于我的问题的最重要的事情。这是代码:
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
deviceInfo: {
name: "Initial Name",
batLevel: "78%",
}
}
}
componentDidMount() {
this.props.requestApiData();
}
updateDeviceInfoWithState (){
const devices = (this.props.data.data);
if(devices){
const newDeviceInfo = this.state.deviceInfo;
newDeviceInfo.name = devices[0].shadow.desired.payload.refAppData.name;
newDeviceInfo.batLevel = devices[0].shadow.reported.payload.refAppData.batteryState.level;
this.setState({
deviceInfo: newDeviceInfo,
});
}
}
render() {
this.updateDeviceInfoWithState()
return (
<div className='container'>
<p> {this.state.deviceInfo.name} </p>
<p> {this.state.deviceInfo.batLevel} </p>
</div>
)
}...
在渲染方法中更新状态不是一个好的做法,因为它可能会导致无限循环。
在你的情况下状态是多余的,因为你只从道具中获取数据,或者用默认值替换它。而不是在updateDeviceInfoWithState
方法中使用return状态name
和batLevel
,而在render
方法中使用它。
示例(未测试):
class Dashboard extends React.Component {
componentDidMount() {
this.props.requestApiData();
}
updateDeviceInfoWithState (){
const devices = this.props.data.data;
if(devices){
const device = devices[0].shadow;
return {
name: device.desired.payload.refAppData.name,
batLevel: device.reported.payload.refAppData.batteryState.level
};
}
return {
name: "Initial Name",
batLevel: "78%",
};
}
render() {
const { name, batLevel } = this.updateDeviceInfoWithState();
return (
<div className='container'>
<p> {name} </p>
<p> {batLevel} </p>
</div>
);
}...
注 1:如果您想将组件与状态分离,最好将简单的属性作为数据的输入。例如,此组件需要 name
和 batLevel
作为属性。它不需要知道设备数组、影子、有效负载等......您可以在 saga 中接收数据时准备数据,或者在 mapStateToProps
中使用 redux selector。
注2:如果你确实需要你所在州的数据,你可以使用旧版本getDerivedStateFromProps
life-cycle method (React 16.3), or update the state in the componentWillReceiveProps
对于这种情况,您可以像这样使用 ComponentWillRecieveProps 方法
componentWillRecieveProps(nextProps) {
// Condition as per ur requirement.
If(this.props.data != nextProps.data) {
this.updateDeviceInfoWithState(nextProps)
}
}
此方法仅会 运行 每当您的组件属性更改时。
目前,当 运行 完成我的 saga 时,我从 API 中以 JSON 格式获取数据。当组件挂载时,抓取过程开始。这意味着组件渲染了两次。
现在,当数据作为道具可用时。我可以使用它来渲染它。
我的方法如下,我有一个:
- 具有初始状态的构造函数
- 我在"componentDidMount" 中获取数据
- 我得到了一个函数,它从 props 中获取 JSON 属性并将其放入新变量中
- 我在我的 render() 函数中 运行 这个函数,当 props 包含获取的数据时
此方法中的问题:一旦组件 运行 成为数据变为 "structured" 的函数,渲染函数就会循环,然后有时,属性的值会在控制台中显示一条警告消息。
我的问题:
- render() 运行一次时如何防止循环?
- 我如何设计它,以便将获取的对象的特定属性合并到一个新对象中以及如何
我希望我描述了关于我的问题的最重要的事情。这是代码:
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
deviceInfo: {
name: "Initial Name",
batLevel: "78%",
}
}
}
componentDidMount() {
this.props.requestApiData();
}
updateDeviceInfoWithState (){
const devices = (this.props.data.data);
if(devices){
const newDeviceInfo = this.state.deviceInfo;
newDeviceInfo.name = devices[0].shadow.desired.payload.refAppData.name;
newDeviceInfo.batLevel = devices[0].shadow.reported.payload.refAppData.batteryState.level;
this.setState({
deviceInfo: newDeviceInfo,
});
}
}
render() {
this.updateDeviceInfoWithState()
return (
<div className='container'>
<p> {this.state.deviceInfo.name} </p>
<p> {this.state.deviceInfo.batLevel} </p>
</div>
)
}...
在渲染方法中更新状态不是一个好的做法,因为它可能会导致无限循环。
在你的情况下状态是多余的,因为你只从道具中获取数据,或者用默认值替换它。而不是在updateDeviceInfoWithState
方法中使用return状态name
和batLevel
,而在render
方法中使用它。
示例(未测试):
class Dashboard extends React.Component {
componentDidMount() {
this.props.requestApiData();
}
updateDeviceInfoWithState (){
const devices = this.props.data.data;
if(devices){
const device = devices[0].shadow;
return {
name: device.desired.payload.refAppData.name,
batLevel: device.reported.payload.refAppData.batteryState.level
};
}
return {
name: "Initial Name",
batLevel: "78%",
};
}
render() {
const { name, batLevel } = this.updateDeviceInfoWithState();
return (
<div className='container'>
<p> {name} </p>
<p> {batLevel} </p>
</div>
);
}...
注 1:如果您想将组件与状态分离,最好将简单的属性作为数据的输入。例如,此组件需要 name
和 batLevel
作为属性。它不需要知道设备数组、影子、有效负载等......您可以在 saga 中接收数据时准备数据,或者在 mapStateToProps
中使用 redux selector。
注2:如果你确实需要你所在州的数据,你可以使用旧版本getDerivedStateFromProps
life-cycle method (React 16.3), or update the state in the componentWillReceiveProps
对于这种情况,您可以像这样使用 ComponentWillRecieveProps 方法
componentWillRecieveProps(nextProps) {
// Condition as per ur requirement.
If(this.props.data != nextProps.data) {
this.updateDeviceInfoWithState(nextProps)
}
}
此方法仅会 运行 每当您的组件属性更改时。