javascriptreactjses5-shim

Passing filtered value to react render()


I use react-datagrid to represent my documents table, but I cannot figure out how to instantiate render() scope with full data. It always instantiate with no data.

this is my datagrid

'use strict';

 var React    = require('react')
 var DataGrid = require('react-datagrid')


 var columns = [
     { name: 'id', title: '#', width: 50 },
     { name: 'business_id', flex: 1 },
     { name: 'lastName'  },
     { name: 'city', flex: 1 },
     { name: 'country', flex: 1 },
     { name: 'email', width: 200 }
  ]

  var App = React.createClass({

    initData: function(documents){
        if(documents){
            return documents;
        } else {
            console.log('documents: '+ this.props.documents);
            return this.props.documents;
        }
    },
    getInitialState: function(){
        return {
            dataSource: [],
        }
    },
    componentDidMount() {
        this.setState({
            dataSource: this.initData()
        })
    },
    render: function(){
      console.log('this.props.documents: '+ this.props.documents)
      return <DataGrid
        idProperty='id'
        dataSource={this.initData()}
        columns={columns}
        style={{height: 400}}

        onFilter={this.handleFilter}
        liveFilter={true} //to apply the filter while typing
     />
    },

   handleFilter: function(column, value, allFilterValues){
    //reset data to original data-array
    var data = this.initData()

    //go over all filters and apply them
    Object.keys(allFilterValues).forEach(function(name){
        var columnFilter = (allFilterValues[name] + '').toUpperCase()

        if (columnFilter == ''){
            return
        }

        data = data.filter(function(item){
            if ((item[name] + '').toUpperCase().indexOf(columnFilter) === 0){
                return true
            }
        })

      })
      this.initData(data)
      this.setState({})
    }
   })

the first console log returns nothind

documents:

the console log in the render() returns data

this.props.documents:[object Object],[object Object],[object Object],[object Object],[object Object]

and this how I call my datagrid component from my home component

<DocumentReactNewGrid documents={this.state.documents}/>

Solution

  • Make the dataSource as a state. On filter, set the new data to the state. This will re-render the component with the new data.

    'use strict';
    
     var React    = require('react')
     var DataGrid = require('react-datagrid')
    
    
    var columns = [
       { name: 'id', title: '#', width: 50 },
       { name: 'business_id', flex: 1 },
       { name: 'lastName'  },
       { name: 'city', flex: 1 },
       { name: 'country', flex: 1 },
       { name: 'email', width: 200 }
    ]
    
    var App = React.createClass({
      initData: function(documents){
        if(documents){
            return documents;
        } else {
            return this.props.documents;
        }
       },
      getInitialState: function(){
        return { 
          dataSource: this.initData(),
        }
      },
      componentWillReceiveProps(nextProps) {
        this.setState({
         dataSource: nextProps.documents,
        })
      },
      render: function(){
        return <DataGrid
            idProperty='id'
            dataSource={this.state.dataSource}
            columns={columns}
            style={{height: 400}}
    
            onFilter={this.handleFilter}
            liveFilter={true} //to apply the filter while typing
        />
       },
    
    
       handleFilter: function(column, value, allFilterValues){
        //reset data to original data-array
        var data = this.initData()
    
        //go over all filters and apply them
        Object.keys(allFilterValues).forEach(function(name){
            var columnFilter = (allFilterValues[name] + '').toUpperCase()
    
            if (columnFilter == ''){
                return
            }
    
            data = data.filter(function(item){
                if ((item[name] + '').toUpperCase().indexOf(columnFilter) === 0){
                    return true
                }
            })
    
          })
          this.setState({
            dataSource: data
          })
        }
       })
    

    Hope this helps!