为什么将 React 组件存储为变量或状态是糟糕的设计实践
Why React Components being stored as variables or as state is bad design practice
我的应用程序进行 API 调用并将 JSON 数组的每个元素转换为 React 组件。
我制作了这些 child 组件的数组,但它们没有呈现。我如何强制他们渲染?我应该使用 React.create()
然后在每个上调用 render()
吗?
什么是合适的 vanilla React 设计模式?
var apiPosts = [];
class PostsItsContainer extends Component {
constructor(props){
super(props);
this.state = {}
}
componentDidMount(){
let uri = "some_API_endpoint" ;
if(uri){
fetch(uri)
.then(data => data.json())
.then(posts => {
posts.data.children.forEach(post => {
let imgUrl = post.data.hasOwnProperty('preview') ? post.data.preview.images[0].source.url : null;
let postData = [post.data.title, imgUrl, post.data.link];
apiPosts.push(<PostIt link={post.data.url} image={imgUrl} title={post.data.title} />);
});
}).catch(err => console.log(err)) }
}
render() {
return (
<div className="PostsItsContainer">
{apiPosts}
</div>
);
}
}
编辑:
我更改了标题,因为它很普通。我真的在问为什么我的方法是糟糕的设计实践并且不会给我正确的结果。
@Jayce444 告诉我原因,@Supra28 给出了很好的答案。我在这里发布@Jayce444 的评论以便于阅读:
It's perfectly possible to store a component in a variable or array and then use that. But the store/props should be reserved for the bare bones data needed to render stuff, not the entire pre-made component. There's s few reasons, two being: firstly you'll bloat the state/props doing that, and secondly you're combining the logic and view functionalities. The data needed to render a component and the actual way it's rendered should be loosely coupled, makes your components easier to maintain, modify and understand. It's like separating HTML and CSS into separate files, it's easier :)
所以我们在这里做的是:
1) 最初将加载状态设置为真
2) 当我们从 api 获取数据时,我们希望我们的组件重新呈现以显示新数据,因此我们将数据保持在状态中。
3) 在渲染函数内部,如果我们的加载指示器为真,我们 return 一个 Loding 指示器或 return 帖子数组(地图 returns 数组)包裹着div.
class PostsItsContainer extends Component {
constructor(props) {
super(props)
this.state = { apiData: [], loadingPosts: true } // Loading state to know that we are loading the data from the api and do not have it yet so we can display a loading indicator and don't break our code
}
componentDidMount() {
let uri = "some_API_endpoint"
if (uri) {
fetch(uri)
.then(data => data.json())
.then(posts => {
this.setState({ apiData: posts.data.children, loadingPosts: false }) //Now we save all the data we get to the state and set loading to false; This will also cause the render function to fire again so we can display the new data
})
.catch(err => console.log(err))
}
}
render() {
if (this.state.loadingPosts) return <div>Loading......</div> //If we haven't recieved the data yet we display loading indicator
return (
<div className="PostsItsContainer">
{this.state.postData.map((post, i) => (
<PostIt
key={i} //You'll need a key prop to tell react this is a unique component use post.id if you have one
link={post.data.url}
image={
post.data.preview ? post.data.preview.images[0].source.url : null
}
title={post.data.title}
/>
))}
</div>
)
}
}
我的应用程序进行 API 调用并将 JSON 数组的每个元素转换为 React 组件。
我制作了这些 child 组件的数组,但它们没有呈现。我如何强制他们渲染?我应该使用 React.create()
然后在每个上调用 render()
吗?
什么是合适的 vanilla React 设计模式?
var apiPosts = [];
class PostsItsContainer extends Component {
constructor(props){
super(props);
this.state = {}
}
componentDidMount(){
let uri = "some_API_endpoint" ;
if(uri){
fetch(uri)
.then(data => data.json())
.then(posts => {
posts.data.children.forEach(post => {
let imgUrl = post.data.hasOwnProperty('preview') ? post.data.preview.images[0].source.url : null;
let postData = [post.data.title, imgUrl, post.data.link];
apiPosts.push(<PostIt link={post.data.url} image={imgUrl} title={post.data.title} />);
});
}).catch(err => console.log(err)) }
}
render() {
return (
<div className="PostsItsContainer">
{apiPosts}
</div>
);
}
}
编辑:
我更改了标题,因为它很普通。我真的在问为什么我的方法是糟糕的设计实践并且不会给我正确的结果。
@Jayce444 告诉我原因,@Supra28 给出了很好的答案。我在这里发布@Jayce444 的评论以便于阅读:
It's perfectly possible to store a component in a variable or array and then use that. But the store/props should be reserved for the bare bones data needed to render stuff, not the entire pre-made component. There's s few reasons, two being: firstly you'll bloat the state/props doing that, and secondly you're combining the logic and view functionalities. The data needed to render a component and the actual way it's rendered should be loosely coupled, makes your components easier to maintain, modify and understand. It's like separating HTML and CSS into separate files, it's easier :)
所以我们在这里做的是:
1) 最初将加载状态设置为真
2) 当我们从 api 获取数据时,我们希望我们的组件重新呈现以显示新数据,因此我们将数据保持在状态中。
3) 在渲染函数内部,如果我们的加载指示器为真,我们 return 一个 Loding 指示器或 return 帖子数组(地图 returns 数组)包裹着div.
class PostsItsContainer extends Component {
constructor(props) {
super(props)
this.state = { apiData: [], loadingPosts: true } // Loading state to know that we are loading the data from the api and do not have it yet so we can display a loading indicator and don't break our code
}
componentDidMount() {
let uri = "some_API_endpoint"
if (uri) {
fetch(uri)
.then(data => data.json())
.then(posts => {
this.setState({ apiData: posts.data.children, loadingPosts: false }) //Now we save all the data we get to the state and set loading to false; This will also cause the render function to fire again so we can display the new data
})
.catch(err => console.log(err))
}
}
render() {
if (this.state.loadingPosts) return <div>Loading......</div> //If we haven't recieved the data yet we display loading indicator
return (
<div className="PostsItsContainer">
{this.state.postData.map((post, i) => (
<PostIt
key={i} //You'll need a key prop to tell react this is a unique component use post.id if you have one
link={post.data.url}
image={
post.data.preview ? post.data.preview.images[0].source.url : null
}
title={post.data.title}
/>
))}
</div>
)
}
}