Передайте это. Состояние не работает ReactJS - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть таблица, которая получает данные и динамически отображает их,

При прохождении «примера» таблица показывает данные без проблем, но когда я пытаюсь передать

, который также содержит ту же структуру, что и пример (массив объектов) это не работает

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>

      );
  }
}

TypeError: Невозможно прочитать свойство '0' из неопределенного const props = Object.keys (data [0]);

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

ReactTable ->

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>
        );
    }
}

Ответы [ 6 ]

0 голосов
/ 24 апреля 2018
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.

Это легко !!!

0 голосов
/ 24 апреля 2018

Вы переопределяете глобальное состояние с помощью

.then((myJson) => this.setState(myJson)), по сути, вы переопределяете this.state новым объектом, который не разрешен, вам всегда нужно только extend this.state, поскольку вы реферрируете в своемкод для this.state.sprints правильного вызова будет

 .then((sprints) => this.setState({sprints))

, который использует использование деструктуризации объектов, так что он будет таким же, как {sprints: sprints React затем объединит this.state (то есть {} в то время отконструктор) и объедините его с {sprints: sprints}, что приведет к правильному состоянию

this.state = {
  sprints: data
}

также ваш код асинхронный, вам нужно добавить проверку внутри рендера, это можно легко сделать, вернув null

if (!this.state.sprints) return null

, который защитит метод рендеринга от ошибок

0 голосов
/ 24 апреля 2018

Проблема в том, что пока ваш запрос не выполнен - ​​ваше состояние пусто, поэтому свойство 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, если в state существует sprints, и использовании загрузчика, как упомянуто Tiago Alves.

0 голосов
/ 24 апреля 2018

Вы делаете вызов API на componentDidMount и отправляете данные на свой компонент на render.

Но render предшествует componentDidMount в жизненном цикле компонента .

Вот почему вы должны проверить, есть ли у вас данные, прежде чем передавать их. Как это:

...
render() {
    return this.state.sprints ? (
      <div>
        <ResponseTable data={example} />
      </div>
    ) : (
      <div>
         Loading ...
      </div>
    );
}

Когда вы загрузите this.state.sprints, ваш компонент обновится и будет запущен повторный рендеринг, отображающий таблицу должным образом.

0 голосов
/ 24 апреля 2018

Вам нужно будет инициализировать состояние sprints значением, если вы хотите использовать его в методе рендеринга, в противном случае он ищет ключ, который не существует.Ваш конструктор может выглядеть примерно так:

constructor(props){
    super(props);
    this.state = {
        sprints: {}    
    };
}
0 голосов
/ 24 апреля 2018

Попробуйте установить имя свойства:

setState({sprints: myJson})

как отсутствует в этой строке:

.then((myJson) => this.setState(myJson));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...