在呈现

时间:2015-06-19 03:59:02

标签: reactjs

我是reactjs的新手,我想在服务器中获取数据,以便将带有数据的页面发送给客户端。

当函数getDefaultProps返回虚拟数据时,可以这样{data:{books:[{..},{..}]}}。

但是不能使用下面的代码。代码按此顺序执行,并显示错误消息“无法读取未定义的属性'书籍”

  1. getDefaultProps
  2. 返回
  3. {data:{books:[{}},{..}]}}
  4. 但是,我希望代码应按此顺序运行

    1. getDefaultProps
    2. {data:{books:[{}},{..}]}}
    3. 返回
    4. 任何想法?

      statics: {
          fetchData: function(callback) {
            var me = this;
      
            superagent.get('http://localhost:3100/api/books')
              .accept('json')
              .end(function(err, res){
                if (err) throw err;
      
                var data = {data: {books: res.body} }
      
                console.log('fetch');                  
                callback(data);  
              });
          }
      
      
      getDefaultProps: function() {
          console.log('getDefaultProps');
          var me = this;
          me.data = '';
      
          this.fetchData(function(data){
              console.log('callback');
              console.log(data);
              me.data = data;      
            });
      
          console.log('return');
          return me.data;            
        },
      
      
        render: function() {
          console.log('render book-list');
          return (
            <div>
              <ul>
              {
                this.props.data.books.map(function(book) {
                  return <li key={book.name}>{book.name}</li>
                })
              }
              </ul>
            </div>
          );
        }
      

8 个答案:

答案 0 :(得分:18)

您正在寻找的是componentWillMount

来自documentation

  

在客户端和服务器上调用一次,紧接着   初始渲染发生。如果您在此方法中致电setState,   render()将看到更新后的状态,并且只会执行一次   尽管状态发生了变化。

所以你会做这样的事情:

componentWillMount : function () {
    var data = this.getData();
    this.setState({data : data});
},

这样,render()只会被调用一次,并且您将拥有您在初始渲染中寻找的数据。

答案 1 :(得分:5)

的一个非常简单的示例
import React, { Component } from 'react';
import { View, Text } from 'react-native';

export default class App extends React.Component  {

    constructor(props) {
      super(props);

      this.state = {
        data : null
      };
    }

    componentWillMount() {
        this.renderMyData();
    }

    renderMyData(){
        fetch('https://your url')
            .then((response) => response.json())
            .then((responseJson) => {
              this.setState({ data : responseJson })
            })
            .catch((error) => {
              console.error(error);
            });
    }

    render(){
        return(
            <View>
                {this.state.data ? <MyComponent data={this.state.data} /> : <MyLoadingComponnents /> }
            </View>
        );
    }
}

答案 2 :(得分:4)

在React中,props用于组件参数,而不是用于处理数据。有一个名为state的单独构造。每当您更新state时,组件基本上会根据新值重新呈现自己。

var BookList = React.createClass({
  // Fetches the book list from the server
  getBookList: function() {
    superagent.get('http://localhost:3100/api/books')
      .accept('json')
      .end(function(err, res) {
        if (err) throw err;

        this.setBookListState(res);
      });
  },
  // Custom function we'll use to update the component state
  setBookListState: function(books) {
    this.setState({
      books: books.data
    });
  },
  // React exposes this function to allow you to set the default state
  // of your component
  getInitialState: function() {
    return {
      books: []
    };
  },
  // React exposes this function, which you can think of as the
  // constructor of your component. Call for your data here.
  componentDidMount: function() {
    this.getBookList();
  },
  render: function() {
    var books = this.state.books.map(function(book) {
      return (
        <li key={book.key}>{book.name}</li>
      );
    });

    return (
      <div>
        <ul>
          {books}
        </ul>
      </div>
    );
  }
});

答案 3 :(得分:4)

我用来从服务器接收数据并显示它的最佳答案

 constructor(props){
            super(props);
            this.state = {
                items2 : [{}],
                isLoading: true
            }

        }

componentWillMount (){
 axios({
            method: 'get',
            responseType: 'json',
            url: '....',

        })
            .then(response => {
                self.setState({
                    items2: response ,
                    isLoading: false
                });
                console.log("Asmaa Almadhoun *** : " + self.state.items2);
            })
            .catch(error => {
                console.log("Error *** : " + error);
            });
    })}



    render() {
       return(
       { this.state.isLoading &&
                    <i className="fa fa-spinner fa-spin"></i>

                }
                { !this.state.isLoading &&
            //external component passing Server data to its classes
                     <TestDynamic  items={this.state.items2}/> 
                }
         ) }

答案 4 :(得分:1)

作为Michael Parker答案的补充,你可以让getData接受一个回调函数来激活setState更新数据:

componentWillMount : function () {
    var data = this.getData(()=>this.setState({data : data}));
},

答案 5 :(得分:0)

如果有人仍然在回答问题后回答了一个类似的问题并提出了一个可能简单的解决方案,问题就在于它涉及到使用redux-sagas:

https://stackoverflow.com/a/38701184/978306

或者直接跳到我就该主题撰写的文章:

https://medium.com/@navgarcha7891/react-server-side-rendering-with-simple-redux-store-hydration-9f77ab66900a

答案 6 :(得分:0)

您可以使用redial包在尝试呈现之前在服务器上预取数据

答案 7 :(得分:0)

我也偶然发现了这个问题,学习了React,并通过显示Spinner直到数据准备好解决了它。

    render() {
    if (this.state.data === null) {
        return (
            <div className="MyView">
                <Spinner/>
            </div>
        );
    }
    else {
        return(
            <div className="MyView">
                <ReactJson src={this.state.data}/>
            </div>
        );
    }
}