我尝试将反应类组件转换为无状态组件,我不是一个具有复杂无状态组件的goood。这样做的最佳做法是什么?现在我已经得到了组件,Table和EnchanceTable,我想将Table转换为无状态,所有的功能都在我内部且没有任何状态。我已经开始使用了这个,但不太确定它是否真的如此。
表组件(应该是无状态的)
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>)
}
}