reactjs - 为什么子组件没有在反应中呈现
问题描述
我的疑问是为什么不调用子组件 LibrarySubChild,而是进行无限渲染
我的库组件正在从本地 url 获取 JSON,然后设置结果
import React, { Component } from 'react';
import LibrarySubChild from './Library';
class Library extends Component {
state = {
libraries: []
};
componentDidMount() {
console.log("library componentDidMount method called");
this.fetchData();
}
fetchData = () => {
fetch('/library/get-all-library',{ mode: 'no-cors'})
.then(res => res.json())
.then((data) => {
this.setState({ libraries: data })
console.log(this.state.libraries)
})
.catch(console.log);
};
render() {
console.log("library render method called");
const arrLength=this.state.libraries.length;
return (
this.state.libraries.length>0 ?
<LibrarySubChild libraries={this.state.libraries} /> : arrLength
);
}
}
export default Library;
下面的组件未呈现
import React, { Component } from 'react';
const LibrarySubChild = ({ libraries }) => {
console.log("library sub child render method called");
return (
<div>
<h1>Contact List</h1>
{libraries.map((library) => (
<div key={library.libid}>
<h5>{library.libName}</h5>
</div>
))}
</div>
)
};
export default LibrarySubChild;
解决此问题的最佳方法是什么
o/p 来自控制台库 componentDidMount 方法称为库 render 方法称为库 componentDidMount 方法称为 (2) [{...}, {...}] 这是控制台输出,它会持续无限时间
解决方案
return/render在componentDidMount之前执行。在 Library componentDidMount之后获取状态库值(其长度决定了 LibrarySubChild 是否被渲染)(应该如此)。这会导致子组件在 componentDidMount 之后发生变化,具体来说,创建了一个 LibrarySubChild 的实例,之后,应该使用新的 LibrarySubChild 创建一个新的 Library 实例。
问题是,为什么 LibrarySubChild 没有被渲染——而不是 Library 中的无限 componentDidMount 循环?
答案:如上所示,这是因为(1)创建了一个新的 Library 实例,其库状态值(在构造函数中)重置为 0,而不是简单地运行一次 componentDidMount,因为 React 的 diffing 算法(更多见下文)和(2)状态库值,它决定渲染什么,在组件生命周期的返回/渲染阶段执行,由于(1.),库的状态必然没有任何值 - 重新安装是因为 Library 的根元素以 ap 开头标记并将 LibrarySubChild 更改为根。
换句话说,请注意在上图中,render 是在 componentDidMount 之前执行的。每当库被实例化(或重新挂载)时,都会执行 fetchData,这会将库状态更改为具有 > 0 个元素,进而导致根元素从 ap 标记更改为 LibrarySubChild,我们知道这会导致重新挂载,然后回到第一方(无限库循环背后的逻辑,从不调用/渲染 LibrarySubChild - 手头的问题)。
现在......您可能在想“componentDidMount 对任何组件只运行一次......总是建议在那里获取数据,对吧......?”
一般来说,当然可以——但重要的是要注意 React 的差异算法(或和解)是是否或任何组件将重新安装的核心。那么,何时必须重新安装组件(从而触发 componentDidMount)?:
每当根元素具有不同的类型时,React 都会拆除旧树并从头开始构建新树。从 to ,或 from to ,或 from to ——其中任何一个都将导致完全重建。
图书馆的根价值在改变吗?事实上,从 ap 标签到超过 p 标签的 LibrarySubChild 组件。
import React, { Component } from 'react';
import LibrarySubChild from './Library';
class Library extends Component {
state = {
libraries: []
};
//componentDidMount RUNS **AFTER RETURN/RENDER**
componentDidMount() {
//Infinitely loops because new instances repeatedly made
//As React's diffing algorithm notes change in underlying
//root element types.
console.log("library componentDidMount method called");
this.fetchData();
}
fetchData = () => {
fetch('/library/get-all-library',{ mode: 'no-cors'})
.then(res => res.json())
.then((data) => {
//Side note: Try not to mutate state directly, like below:
Suggestion: this.setState({libraries [...this.state.libraries, data]})
this.setState({ libraries: data })
console.log(this.state.libraries)
})
.catch(console.log);
};
render() {
console.log("library render method called");
const arrLength=this.state.libraries.length;
return (
this.state.libraries.length>0 ?
<LibrarySubChild libraries={this.state.libraries} /> : 0
);
}
}
export default Library;
祝你好运,莫
推荐阅读
- vba - 使用 Application.Workbooks.Open 打开 .txt 文件,但它会删除长数字
- tsql - 日期集之间的 datediff
- jquery - ASP.NET Webforms,将参数传递给后面的代码
- ubuntu - npm 错误!当我这样做时出现 errno ECONNREFUSED:npm install
- javascript - React,在 useEffect 中使用 RequestAnimationFrame 进行动画处理
- flutter - Flutter http - 无效参数:使用 jsonEncode 时请求正文无效
- python - LSTM 中的分类返回相同的分类值
- reactjs - 如何使反应输入显示状态值-ReactJS
- computer-vision - 带有appsink的Gstreamer tee分支减慢了整个管道,如何处理缓冲区异步?
- android - 如果在recyclerview适配器中退出应用程序,Android如何保存复选框状态