2016-08-11 2 views
0

У меня есть пустой массив состояний, когда я пытаюсь изменить состояние с помощью update-addons-update, я получил эту ошибку invariant.js:38 Uncaught (in promise) Error: update(): expected target of $push to be an array; got [object Object].(…). Вот код:ReactJS правильный способ нажать состояние типа массива

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import Helmet from "react-helmet"; 
import axios from 'axios'; 
import { browserHistory } from 'react-router'; 
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'; 
import {encrypt, decrypt} from '../utils/pgp.js'; 
import update from 'react-addons-update'; 


export default class Passwords extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      bunny: [], 
      loaded: false 
     } 
    } 

    componentDidMount =() => { 
     (async function(){ 
      let bugs = await axios.get('/api/vault/', { 
       headers: {'Authorization': "JWT " + sessionStorage.getItem('token')} 
      }); 
      let hiren = []; 
      bugs.data.forEach(async data => { 
       let temp = {}; 
       temp['id'] = data.id; 
       temp['site_url'] = data.site_url; 
       temp['tag'] = data.tag; 
       temp['email'] = await decrypt(sessionStorage.getItem('key'), data.email); 
       temp['username'] = await decrypt(sessionStorage.getItem('key'), data.username); 
       temp['password'] = await decrypt(sessionStorage.getItem('key'), data.password); 
       temp['note'] = await decrypt(sessionStorage.getItem('key'), data.note); 
       temp['created_at'] = data.created_at; 
       temp['updated_at'] = data.updated_at; 

       hiren.push(temp); 
      }); 
      //this.setState({bunny: hiren}); <-- renders empty table 
      this.setState(update(this.state, {$push: hiren})); 
      this.setState({loaded: true}); 
      console.log(this.state.bunny); 
     }.bind(this))(); 
    } 

    render() { 

     function anchor(cell, row){ 
      let a; 
      if (cell.startsWith('http://')) 
       a = cell.slice(7); 
      else if (cell.startsWith('https://')) 
       a = cell.slice(8); 
      return '<a href=' + cell + '>' + a + '</a>' ; 
     } 
     if(this.state.loaded) { 
      return (
       <div> 
        <Helmet 
         title="Vault-> Passwords" 
        /> 
        <BootstrapTable data={this.state.bunny} striped={true} hover={true} condensed={true} pagination={true} search={true}> 
         <TableHeaderColumn dataField="id" isKey={true}>ID</TableHeaderColumn> 
         <TableHeaderColumn dataField="site_url" dataFormat={anchor} dataSort={true}>URL</TableHeaderColumn> 
         <TableHeaderColumn dataField="email">Email</TableHeaderColumn> 
         <TableHeaderColumn dataField="username">Username</TableHeaderColumn> 
         <TableHeaderColumn dataField="password">Password</TableHeaderColumn> 
         <TableHeaderColumn dataField="note">Note</TableHeaderColumn> 
         <TableHeaderColumn dataField="tag">Tag</TableHeaderColumn> 
         <TableHeaderColumn dataField="created_at">Created At</TableHeaderColumn> 
         <TableHeaderColumn dataField="updated_at">Updated At</TableHeaderColumn> 
        </BootstrapTable> 
       </div> 
      ) 
     } 
     return <div>loading.... </div> 
    } 
} 

Итак, каков правильный способ ввода массивов в состояние?

+1

Я думаю, что у вас есть синтаксическая ошибка. Ты, наверное, не вдавливаешься в кролика. –

+0

show 'console.log'' hiren' перед 'this.setState ({bunny: hiren});' – Maxx

+0

также я бы не вызывал setState несколько раз, каждый раз, когда вы вызываете функцию рендеринга setState, вызывается, что не требуется, если вы объединяете все обновления в одном вызове обновления состояния –

ответ

2

Попробуйте с this.setState(update(this.state, {bunny: { $push: hiren } }))
И вы используете функции async в вашем forEach. переменная hiren будет пуста к тому времени, когда вызывается setState.

Смежные вопросы