通过this.state不工作ReactJS

时间:2018-04-24 12:46:18

标签: javascript reactjs api fetch

我有一张表来获取数据并动态显示它,

传递"示例"该表显示数据没有问题, 但是当我试图通过时

< ResponseTable data = {this.state.sprints},

它也包含与示例相同的结构(对象数组) 它不起作用



var example = [
  {id: 1, sequence: 2, name: "Sprint 2018", state: "CLOSED", linkedPagesCount: 0},
  {id: 2, sequence: 2, name: "Sprint 2018-1", state: "OPEN", linkedPagesCount: 0}
];


class Table extends React.Component{

  constructor(props){
    super(props);
    this.state = {}
  }

  fetchData() {
fetch('http://localhost:8000/sprints/23')
  .then(function(response) {
    return response.json();
  })
  .then((myJson) => this.setState(myJson));
}

  componentDidMount(){
    this.fetchData();
  }

  render(){
    console.log(this.state.sprints)
    console.log(example)
    return(
      <div>
        <ResponseTable data={example} />
      </div>

      );
  }
}
&#13;
&#13;
&#13;

TypeError:无法读取属性&#39; 0&#39;未定义的 const props = Object.keys(data [0]);

&#13;
&#13;
columnsBuilder (data) {        
> 12 |     const props = Object.keys(data[0]);
  13 |     const columns = props.map( (item, index) => ({
  14 |         Header : item,
  15 |         accessor : item,
&#13;
&#13;
&#13;

ReactTable - &gt;

&#13;
&#13;
export default class ResponseTable extends React.Component {
 
    constructor() {
        super();
        this.columnsBuilder = this.columnsBuilder.bind(this);
    }
    columnsBuilder (data) {        
        const props = Object.keys(data[0]);
        const columns = props.map( (item, index) => ({
            Header : item,
            accessor : item,
            Cell : propss => propss.original[item].length === 0 ? '[]' : propss.original[item].toString(),
        }));
 
        const built = [
            {
                Header : 'Response',
                columns,
            },
        ];        
        return built;
    }
 
    render() {
        return (
            <div>
                <ReactTable
                    data={this.props.data}
                    columns={this.columnsBuilder(this.props.data)}
                    defaultPageSize={10}
                    className="-striped -highlight"
                />
                <br />
            </div>
        );
    }
}
&#13;
&#13;
&#13;

6 个答案:

答案 0 :(得分:1)

您正在Curl failed with return code: 3221226356. 拨打API,并通过componentDidMount将数据发送到您的组件。

但是render位于component lifecyclerender之前。

这就是为什么你需要在传递数据之前验证是否有数据。像这样:

componentDidMount

当你加载... render() { return this.state.sprints ? ( <div> <ResponseTable data={example} /> </div> ) : ( <div> Loading ... </div> ); } 时,你的组件会更新并触发重新渲染,正确显示表格。

答案 1 :(得分:1)

export default class ResponseTable extends React.Component {

    constructor(props) { // Use Props
        super(props); // Use Props
        this.columnsBuilder = this.columnsBuilder.bind(this);
    }
    columnsBuilder () { //Remove data
        const props = Object.keys(this.props.data[0]); //Use Props
        const columns = props.map( (item, index) => ({
            Header : item,
            accessor : item,
            Cell : propss => propss.original[item].length === 0 ? '[]' : propss.original[item].toString(),
        }));

        const built = [
            {
                Header : 'Response',
                columns,
            },
        ];        
        return built;
    }

    render() {
        return (
            <div>
                <ReactTable
                    data={this.props.data}
                    columns={this.columnsBuilder()} // Remove Props
                    defaultPageSize={10}
                    className="-striped -highlight"
                />
                <br />
            </div>
        );
    }
}

请检查propss用于Cell的用途。

这很容易!!!

答案 2 :(得分:0)

尝试设置属性名称:

setState({sprints: myJson})

因为它在这一行中缺失:

.then((myJson) => this.setState(myJson));

答案 3 :(得分:0)

如果要在render方法中使用它,则需要使用值初始化sprints状态,否则它将查找不存在的键。 您的构造函数可能如下所示:

constructor(props){
    super(props);
    this.state = {
        sprints: {}    
    };
}

答案 4 :(得分:0)

在您的请求完成之前的问题 - 您的状态为空,因此没有sprints属性。

您应该将其添加到Table组件中的构造函数中。

组件。

  constructor(props){
    super(props);
    this.state = {
        sprints: []
    }
  }

此外,您应该在columnsBuilder方法中检查数据中是否有项目,因为它也会产生错误。

ResponseTable 组件。

columnsBuilder (data) {        
    const props = data.length ? Object.keys(data[0]) : data;
    const columns = props.map( (item, index) => ({
        Header : item,
        accessor : item,
        Cell : propss => propss.original[item].length === 0 ? '[]' : propss.original[item].toString(),
    }));

    const built = [
        {
            Header : 'Response',
            columns,
        },
    ];        
    return built;
}

另一种方法是,如果render中存在sprints,则检查state方法并按照Tiago Alves使用加载程序。

答案 5 :(得分:0)

你用

覆盖全球状态

.then((myJson) => this.setState(myJson))基本上你用新对象覆盖this.state,不允许你总是只需要extend this.state,因为你在代码中{{1}正确的通话将是

this.state.sprints

利用对象的解构使它与 .then((sprints) => this.setState({sprints)) 相同然后React将合并{sprints: sprints(当时是构造函数的{}}并将其与this.state合并这将导致正确的状态

{sprints: sprints}

你的代码也是异步的你需要在渲染中添加check,它可以通过返回null

轻松完成

this.state = { sprints: data }

将保护render方法免于错误