【问题标题】:Wait for react-promise to resolve before render在渲染之前等待 react-promise 解决
【发布时间】:2017-02-09 09:06:03
【问题描述】:

所以我有大量从 API 检索的数据。我认为问题在于我的组件在从 Promise 接收到数据之前调用了 renderMarkers 函数。

所以我想知道如何在调用我的 renderMarkers 函数之前等待完全解析数据的承诺?

class Map extends Component {

componentDidMount() {
  console.log(this.props)
  new google.maps.Map(this.refs.map, {
    zoom: 12,
    center: {
      lat: this.props.route.lat,
      lng: this.props.route.lng
    }
  })
}

componentWillMount() {
  this.props.fetchWells()
}

renderMarkers() {
  return this.props.wells.map((wells) => {
    console.log(wells)
  })
}

render() {
  return (
    <div id="map" ref="map">
      {this.renderMarkers()}
    </div>
  )
 }
} 

function mapStateToProps(state) {
  return { wells: state.wells.all };
}

export default connect(mapStateToProps, { fetchWells })(Map);

【问题讨论】:

  • componentDidMount生命周期方法中获取服务器数据。看看 Dan Abramov 的 this tweet
  • 谢谢,我把它改了,但是在数据返回之前组件仍在调用渲染函数

标签: javascript reactjs


【解决方案1】:

您可以这样做以显示 Loader,直到获取所有信息:

class Map extends Component {
  constructor () {
    super()
    this.state = { wells: [] }
  }

  componentDidMount() {
    this.props.fetchWells()
      .then(res => this.setState({ wells: res.wells }) )
  }

  render () {
    const { wells } = this.state
    return wells.length ? this.renderWells() : (
      <span>Loading wells...</span>
    )
  }
}

【讨论】:

    【解决方案2】:

    对于带有钩子的功能组件:

        function App() {
            
              const [nodes, setNodes] = useState({});
              const [isLoading, setLoading] = useState(true);
            
              useEffect(() => {
                getAllNodes();
              }, []);
            
              const getAllNodes = () => {
                axios.get("http://localhost:5001/").then((response) => {
                  setNodes(response.data);
                  setLoading(false);
                });
              };
            
            
              if (isLoading) {
                return <div className="App">Loading...</div>;
              }
              return (
                <>
                  <Container allNodes={nodes} />
                </>
            
              );
    }
    

    【讨论】:

      【解决方案3】:

      所以我有类似的问题,我自己做出反应并找到了解决方案。通过使用 Async/Await 调用 react 下面是代码sn-p请试试这个。

       import Loader from 'react-loader-spinner'
      
       constructor(props){
          super(props);
          this.state = {loading : true}
        }
        getdata = async (data) => {
          return await data; 
        }
        getprops  = async (data) =>{
          if (await this.getdata(data)){
            this.setState({loading: false})
          }
        }
        render() {
        var { userInfo , userData} = this.props;
          if(this.state.loading == true){
            this.getprops(this.props.userData);
          } 
          else{
      //perform action after getting value in props
          }
          return (
            <div>
            {
                 this.state.loading ? 
                   <Loader
                     type="Puff"
                     color="#00BFFF"
                     height={100}
                     width={100}
                   />
                 :    
                    <MyCustomComponent/> // place your react component here
            }
            </div>
            )
      }
      

      【讨论】:

        【解决方案4】:

        在 API 调用完成之前调用渲染函数是可以的。 wells 是一个空数组(初始状态),您只需不渲染任何内容。并且在从 API 接收到数据后,你的组件会因为 props(redux store)的更新而自动重新渲染。所以我看不出问题。

        如果你真的想在接收 API 数据之前阻止它渲染,只需在你的渲染函数中检查,例如:

        if (this.props.wells.length === 0) {
          return null
        }
        
        return (
          <div id="map" ref="map">
            {this.renderMarkers()}
          </div>
        )
        

        【讨论】:

        • 请注意,您提到的用例只是一种可能性。实际上,如果您已经有数据,比如说整个enterprises 列表,然后您想去某个地方仅列出几家企业,那么您首先会看到整个列表,然后它会缩小。这似乎很奇怪。因此,在显示过滤列表之前,应该能够检查 Promise 是否已解决。
        猜你喜欢
        • 1970-01-01
        • 2020-08-14
        • 1970-01-01
        • 2021-11-21
        • 2019-05-28
        • 2017-04-02
        • 1970-01-01
        • 2017-01-14
        • 1970-01-01
        相关资源
        最近更新 更多