0

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

我制作了这些子组件的数组,但它们不渲染。我如何强制他们渲染?我应该使用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 的评论以便于阅读:

完全可以将组件存储在变量或数组中,然后使用它。但是 store/props 应该保留用于渲染所需的基本数据,而不是整个预制组件。有几个原因,两个是:首先你会膨胀 state/props 这样做,其次你正在结合逻辑和视图功能。渲染组件所需的数据及其渲染的实际方式应该是松散耦合的,使您的组件更易于维护、修改和理解。这就像将 HTML 和 CSS 分离到单独的文件中一样,更容易:)

4

1 回答 1

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>
    )
  }
}
于 2018-06-04T05:15:56.013 回答