2017-08-14 115 views
0

我嘗試將反應類組件轉換爲無狀態組件,我不是一個複雜的無狀態組件。最佳做法是什麼?現在我必須使用組件,Table和EnchanceTable,我希望將Table轉換爲無狀態,並且具有所有我沒有任何狀態的功能。我已經開始與thsi,但不太確定是真的。將反應類組件轉換爲反應無狀態組件

表組分(應該是無狀態)

class Table extends React.Component { 

    static propTypes = { 
     columns: PropTypes.arrayOf(columnsShape), 
    } 

    constructor(props) { 
     super(props) 
     this.state = { 
      order: 'asc', 
      orderBy: this.props.orderBy, 
      selected: [], 
      searchValue: '', 
      data: this.props.data, 
      filterData: this.props.data, 
     } 
    } 

    defaultCellRenderer = ({item, dataKey}) => 
     item[dataKey] 

    handleRequestSort = (event, property) => { 
     const orderBy = property 
     let order = 'desc' 

     if (this.state.orderBy === property && this.state.order === 'desc') { 
      order = 'asc' 
     } 

     const filterData = this.state.filterData.sort(
     (a, b) => order === 'desc' ? b[orderBy] > a[orderBy] : a[orderBy] > b[orderBy], 
    ) 

     this.setState({ filterData, order, orderBy }) 
    } 

    handleSelectAllClick = (event, checked) => { 
     const {data,selected, onSelectAll} = this.props 
     if (checked) { 
      this.setState({ selected: this.state.data.map(item => item.id) }) 
     } 
     else 
     this.setState({ selected: [] }) 
    } 

    unselectSelected =() => { 
     this.setState({selected: []}) 
    } 

    deleteSelected =() => { 
     const {data, selected, onDelete} = this.props 

     onDelete(selected) 
    } 

    handleKeyDown = (event, id) => { 
     if (keycode(event) === 'space') { 
      this.handleClick(event, id) 
     } 
    } 

    handleClick = (event, id) => { 
     const { selected } = this.state 
     const selectedIndex = selected.indexOf(id) 
     let newSelected = [] 

     if (selectedIndex === -1) { 
      newSelected = newSelected.concat(selected, id) 
     } else if (selectedIndex === 0) { 
      newSelected = newSelected.concat(selected.slice(1)) 
     } else if (selectedIndex === selected.length - 1) { 
      newSelected = newSelected.concat(selected.slice(0, -1)) 
     } else if (selectedIndex > 0) { 
      newSelected = newSelected.concat(
     selected.slice(0, selectedIndex), 
     selected.slice(selectedIndex + 1), 
    ) 
     } 

     this.setState({ selected: newSelected }) 
    } 

    handleSearch = event => { 
     const {data} = this.state 
     let filteredDatas = [] 
     filteredDatas = data.filter(e => { 
      let mathedItems = Object.values(e) 
      let returnedItems 
      mathedItems.forEach(e => { 
       const regex = new RegExp(event.target.value, 'gi') 
       if (typeof e == 'string') 
        returnedItems = e.match(regex) 
      }) 
      return returnedItems 
     }) 
     this.setState({filterData: filteredDatas, searchValue: event.target.value}) 
    } 

    isSelected = id => this.state.selected.indexOf(id) !== -1; 

    render() { 
     const { data, order, orderBy, selected } = this.state 
     const {selectable, columns, children, filtering, numSelected, ...others} = this.props 
     return (
     <div> 
      {selectable && 
       <EnhancedTableToolbar 
        numSelected={selected.length} 
        handleSearch={this.handleSearch} 
        value={this.searchValue} 
        unselectSelected={this.unselectSelected} 
        deleteSelected={this.deleteSelected} 
       /> } 
      <MuiTable > 
       {selectable 
        ? <EnhancedTableHead 
         columns={columns} 
         numSelected={selected.length} 
         order={order} 
         orderBy={orderBy} 
         onSelectAllClick={this.handleSelectAllClick} 
         onRequestSort={this.handleRequestSort} 
         /> 
       : <TableHead> 
        <TableRow > 
         {columns.map(({dataKey, label}) => 
          <TableCell> 
            {label} 
          </TableCell>)} 
        </TableRow> 
       </TableHead> 
       } 
       <TableBody> 
       {data.map((item, index) => { 
        const isSelected = this.isSelected(item.id) 
        return selectable 
         ? <TableRow 
          hover 
          onClick={event => this.handleClick(event, item.id)} 
          onKeyDown={event => this.handleKeyDown(event, item.id)} 
          role="checkbox" 
          aria-checked={isSelected} 
          tabIndex="-1" 
          key={item.id} 
          selected={isSelected} 
          > 
          <TableCell checkbox> 
          <Checkbox checked={isSelected}/> 
          </TableCell> 
          {columns.map(({dataKey, cellRenderer, numeric}) => 
           <TableCell numeric={numeric}> 
            {(cellRenderer || this.defaultCellRenderer)({item, dataKey})} 
           </TableCell>)} 
         </TableRow> 
         : <TableRow hover> 
          {columns.map(({dataKey, cellRenderer, numeric}) => 
           <TableCell numeric={numeric}> 
            {(cellRenderer || this.defaultCellRenderer)({item, dataKey})} 
           </TableCell>)} 
         </TableRow> 
       })} 
       </TableBody> 
      </MuiTable> 
     </div> 
     )} 
} 

EnchancedTable類成分(交互性成分)

const columns = [ 
    { 
     dataKey: 'deviceType', 
     label:'Device Type', 
     numeric: false, 
    }, { 
     dataKey: 'deviceID', 
     label:'Device ID', 
     sortable: true, 
     numeric: true, 
     // cellRenderer: ({item, dataKey}) => 
     //   <Button >Default</Button>, 
    }, { 
     dataKey: 'name', 
     label: 'Name', 
     sortable: true, 
     numeric: false, 

    },{ 
     dataKey: 'currentVersion', 
     label: 'Current Version', 
     sortable: true, 
     numeric: false, 
    },{ 
     dataKey: 'location', 
     label: 'Location', 
     sortable: true, 
     numeric: false, 
    },{ 
     dataKey: 'status', 
     label: 'Status', 
     sortable: true, 
     numeric: false, 
    },{ 
     dataKey: 'lastAliveMessage', 
     label: 'Last alive message', 
     sortable: true, 
     numeric: false, 
    }, { 
     dataKey: 'action', 
     label: 'Actions', 
     cellRenderer:() => <SimpleMenu />, 
    }] 

const data = [ 
    { id: 1, deviceType: 'Tag', deviceID: 1, name:'Tag For sending an ', location: 'Room_104', status: 'assigned'}, 
    { id: 2, deviceType: 'Tag', deviceID: 2, name:'Tag For sending an ', location: 'Room_104', status: 'assigned'}, 
    { id: 3, deviceType: 'Tag', deviceID: 3, name:'Tag For sending an ', location: 'Room_104', status: 'assigned'}, 
    { id: 4, deviceType: 'Tag', deviceID: 4, name:'Tag For sending an ', location: 'Room_104', status: 'assigned'}, 
    { id: 5, deviceType: 'Tag', deviceID: 5, name:'Tag For sending an ', location: 'Room_104', status: 'assigned'}, 
] 

class EnhancedTable extends {Component} { 
    state = { 
     selected: [], 
     data, 
    } 

    render =() => { 
     const {selected, data} = this.state 

     return (
      <Paper> 
       <Table 
        data={data} 
        selectable 
        columns={columns} 
        orderBy='deviceId' 
        selected={selected} 
        onSelect={selected => this.setState({selected})} 
        onDelete={items => this.setState({data: data.filter((item, index) => !items.includes(index))})} 
        onSelectAll={} 
       /> 
      </Paper>) 
    } 
} 
+0

您的組件正在使用內部狀態,因此您無法將它1:1移植到無狀態組件。它需要分解成多個。 – m90

+0

無狀態組件應該很小,並且它們不應該有任何邏輯。無狀態組件就是獲取一些參數,並使用參數返回一個組件。你應該把你的課分成多個小的無狀態組件 – Tarun

+0

我想將所有的邏輯與狀態一起移動到EnchanceTable組件中,一個離開表組件作爲父無狀態組件,它只接收道具。 –

回答

0

實現一種無狀態的組分在反應是使用recompose的最佳方式。你可以看到我的this答案。

相關問題