为什么React组件被存储为变量或状态是糟糕的设计实践

时间:2018-06-04 04:44:52

标签: javascript reactjs react-component

我的应用程序进行API调用,并将JSON数组的每个元素转换为React Component。

我创建了这些子组件的数组,但它们没有渲染。如何强制它们渲染?我应该使用React.create()然后再调用render()吗?

适合的香草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的评论,因为它很容易阅读:

  

将组件存储在变量或数组中然后使用它是完全可能的。但是商店/道具应该保留用于渲染东西所需的裸骨数据,而不是整个预制组件。有几个原因,其中两个原因是:首先,你会膨胀状态/道具,然后你将逻辑和视图功能结合起来。呈现组件所需的数据及其呈现的实际方式应该松散耦合,使您的组件更易于维护,修改和理解。就像将HTML和CSS分成单独的文件一样,它更容易:)

1 个答案:

答案 0 :(得分:2)

所以我们在这里做的是:

1)最初将加载状态设置为true

2)当我们从api获取数据时,我们希望我们的组件重新呈现以显示新数据,因此我们将数据保持在状态。

3)在渲染函数内部,如果我们的加载指示符为真,则返回一个Loding指示符,或返回包含div的帖子数组(map返回一个数组)。

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>
    )
  }
}