子数据组件在数据从发布请求返回之前呈现,导致空白屏幕

时间:2017-10-23 16:53:56

标签: reactjs

在发布请求之后,数据发布到数据库并返回到响应中,但是道具没有及时传递,导致在道具中导致空白屏幕的未定义错误。 ApiManager是一个处理请求的通用crud控制器。我想知道我应该使用componentWillReceiveProps componentDidUpdate还是shouldComponentUpdate,以及通常适当更新子组件的最佳做法

import React, { Component } from 'react'
import ZoneData from './ZoneData'
import { ApiManager }  from '../utils'

class Zones extends Component {
  constructor(){
    super()
    this.state = {
      zone:{
        name:'',
        zipcode: ''
      },
      list: []
    }
  }

  componentDidMount(){
    ApiManager.get('http://localhost:3033/api/zone', null, (err, response) => {
      if(err){
        console.log(err)
        return
      }
      console.log(response)
      this.setState({
        list: response.results
      })
    })
  }

  updateZone (event) {
    event.preventDefault()
    console.log('updateZone: '+event.target.id+'=='+event.target.value)
    let updateZone = Object.assign({}, this.state.zone)
    updateZone[event.target.id] = event.target.value
    this.setState({
      zone: updateZone
    })
  }

  addZone () {
    let updatedZone = Object.assign({}, this.state.zone)
    ApiManager.post('http://localhost:3033/api/zone', updatedZone, (err, response) => {
      if(err){
        alert('ERROR '+err.message)
        return
      }
      console.log("Post created: "+JSON.stringify(response))
      let zoneList = Object.assign([], this.state.list)
      zoneList.push(response.result)
        this.setState({
            list: zoneList
        })          
    })
  }

  render(){
    const listItems = this.state.list.map((zone, i) => {
      return <li className="list-group-item"  key={i}><ZoneData currentZone={zone}/></li>
    })
    return (
      <div className="position-sticky">
      <ul className="list-group">
        {listItems}
      </ul>
        <input id='name' onChange={this.updateZone.bind(this)} className='form-control' placeholder="name"/>
        <input id='zipcode' onChange={this.updateZone.bind(this)} className='form-control' placeholder="zipcode"/>
        <button onClick={this.addZone.bind(this)} className='btn btn-primary'>Add Zone</button>
      </div>
    )
  }
}

export default Zones

子组件

import React, { Component } from 'react'

const ZoneData = (props) => {
 return (
    <div className="container">
      <h2><a href="#">{props.currentZone.name}</a></h2>
      <span>{props.currentZone.zipcode}</span><br/>
      <span>{props.currentZone.numPosts}</span>
    </div>
  )
}

export default ZoneData

子组件props.currentZone.name在发出请求后返回为未定义,并且屏幕变为空白而不更新子组件道具。 当我刷新发布到数据库的新数据时

3 个答案:

答案 0 :(得分:2)

我认为,您应该添加一些像isListReady这样的变量来检查列表是否已准备好显示,一切都会好的。

render(){
    const {list} = this.state;
    const isListReady = list && list.length; 

    const listItems = isListReady && list.map((zone, i) => {
      return <li className="list-group-item"  key={i}><ZoneData currentZone={zone}/></li>
    })

    return (
      <div className="position-sticky">
      <ul className="list-group">
        {isListReady && listItems}
      </ul>
        <input id='name' onChange={this.updateZone.bind(this)} className='form-control' placeholder="name"/>
        <input id='zipcode' onChange={this.updateZone.bind(this)} className='form-control' placeholder="zipcode"/>
        <button onClick={this.addZone.bind(this)} className='btn btn-primary'>Add Zone</button>
      </div>
    )
  }

答案 1 :(得分:0)

您将收到空白屏幕,因为您应该使用componentWillMount()而不是componentDidMount()componentDidMount()在组件呈现后进行api调用。而且我认为你也需要对listItems进行条件渲染。像这样:

render(){
    const listItems = this.state.list.map((zone, i) => {
      return <li className="list-group-item"  key={i}><ZoneData currentZone={zone}/></li>
    })
    return (
      <div className="position-sticky">
      <ul className="list-group">
        {this.state.isListAvailable && listItems}
      </ul>
        {// other code}
      </div>
    )
  }

如果您有列表和数据,则可以将isListAvailable设置为true

答案 2 :(得分:0)

也许它的休假时间,但它是一个回应错字。结果应该是响应。结果