我已经创建了一个组件来对HTML表进行排序和筛选。该功能是正确的,但我的表呈现"No“时遇到了一个问题。但是当我单击其中一个标头时,它将显示数据数组的内容处于状态。我真的对这种奇怪的行为感到困惑和困惑。我认为问题可能与filterAssets函数有关,因为如果我从以下内容中更改:
let filterAssets = this.state.data.filter(a => {
return a.name.toLowerCase().indexOf(this.state.search) !== -1
})对此:
let filterAssets = this.props.assetManagement.filter(a => {
return a.name.toLowerCase().indexOf(this.state.search) !== -1
})这是下面的代码,如果有帮助的话
import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { getAssetManagement } from '../../actions/asset-management'
class AssetManagement extends Component {
static propTypes = {
assetManagement: PropTypes.array.isRequired,
getAssetManagement: PropTypes.func.isRequired
}
componentDidMount() {
this.props.getAssetManagement()
}
state = {
name: '',
search: '',
data: []
}
sortBy = this.sortBy.bind(this)
compareBy = this.compareBy.bind(this)
onSubmit = e => {
e.preventDefault()
}
onChange = e =>
this.setState({
[e.target.name]: e.target.value
})
updateSearch = e =>
this.setState({
search: e.target.value.substr(0, 20)
})
compareBy(key) {
return (a, b) => {
if (a[key] < b[key]) return -1
if (a[key] > b[key]) return 1
return 0
}
}
sortBy(key) {
let arrayCopy = [...this.props.assetManagement]
this.state.data.sort(this.compareBy(key))
this.setState({ data: arrayCopy })
}
render() {
let filterAssets = this.state.data.filter(a => {
return a.name.toLowerCase().indexOf(this.state.search) !== -1
})
return (
<Fragment>
{/* Search input */}
<div class="input-group mb-1">
<div class="input-group-prepend">
<span class="input-group-text btn-secondary">
<i class="fas fa-search" />
</span>
</div>
<input
className="form-control"
type="text"
placeholder="Search Asset"
onChange={this.updateSearch.bind(this)}
value={this.state.search}
/>
</div>
{/* Asset management table */}
<div className="table-responsive">
<table className="table table-bordered text-center">
<thead>
<tr>
<th onClick={() => this.sortBy('id')}>ID</th>
<th onClick={() => this.sortBy('name')}>Name</th>
</tr>
</thead>
<tbody>
{filterAssets != 0 ? (
filterAssets.map(a => (
<tr key={a.id}>
<td>{a.id}</td>
<td>{a.name}</td>
</tr>
))
) : (
<tr>
<td colSpan={6}>No asset records found.</td>
</tr>
)}
</tbody>
</table>
</div>
</Fragment>
)
}
}
const mapStateToProps = state => ({
assetManagement: state.assetManagement.assetManagement
})
export default connect(
mapStateToProps,
{ getAssetManagement }
)(AssetManagement)发布于 2019-04-23 10:09:32
将filterAssets != 0更改为filterAssets.length > 0
第一次渲染:
let filterAssets = this.state.data.filter(a => {
return a.name.toLowerCase().indexOf(this.state.search) !== -1
})您的this.state.data是空的,只有this.props.assetManagement可用,如果您正确地处理redux,那么难怪您无法从过滤中得到任何东西。
顺便说一句:filterAssets != 0是绝对错误的,所以请先修改这一行。
发布于 2019-04-23 10:32:32
在不使用构造函数的情况下,对React组件使用替代语法时,您就不能再访问道具。因此,如果重新使用标准构造函数,问题就会消失,例如:
constructor(props) {
super(props);
this.state = {
name: "",
search: "",
data: this.props.assetManagement
};
this.sortBy = this.sortBy.bind(this);
this.compareBy = this.compareBy.bind(this);
}发布于 2019-04-23 10:43:38
这里真正的问题是,您有两个数据源:state.data和props.assetManagement --从redux检索并从props.assetManagement获取最新数据,但是当需要触发排序时,可以复制到state.data。然后就会出现问题,因为在触发props.assetManagement函数之前,您不会从state.data复制到sortBy。
解决方案是摆脱state.data并将排序键存储在状态中。您可以更新、重置该键值,并且排序逻辑仅适用于props.assetManagement:
class AssetManagement extends Component {
static propTypes = {
assetManagement: PropTypes.array.isRequired,
getAssetManagement: PropTypes.func.isRequired
}
componentDidMount() {
this.props.getAssetManagement()
}
state = {
name: '',
search: '',
sortingKey: ''
}
sortBy = this.sortBy.bind(this)
compareBy = this.compareBy.bind(this)
onSubmit = e => {
e.preventDefault()
}
onChange = e =>
this.setState({
[e.target.name]: e.target.value
})
updateSearch = e =>
this.setState({
search: e.target.value.substr(0, 20)
})
compareBy(key) {
return (a, b) => {
if (a[key] < b[key]) return -1
if (a[key] > b[key]) return 1
return 0
}
}
sortBy(key) {
if (key !== this.state.sortingKey) {
this.setState({ sortingKey: key });
}
}
render() {
let sortAssets = !!this.state.sortingKey ?
this.props.assetManagement.sort(this.compareBy(this.state.sortingKey)) :
this.props.assetManagement;
let filterAssets = sortAssets.filter(a => {
return a.name.toLowerCase().indexOf(this.state.search) !== -1
});
return (
<Fragment>
{/* Search input */}
<div class="input-group mb-1">
<div class="input-group-prepend">
<span class="input-group-text btn-secondary">
<i class="fas fa-search" />
</span>
</div>
<input
className="form-control"
type="text"
placeholder="Search Asset"
onChange={this.updateSearch.bind(this)}
value={this.state.search}
/>
</div>
{/* Asset management table */}
<div className="table-responsive">
<table className="table table-bordered text-center">
<thead>
<tr>
<th onClick={() => this.sortBy('id')}>ID</th>
<th onClick={() => this.sortBy('name')}>Name</th>
</tr>
</thead>
<tbody>
{filterAssets != 0 ? (
filterAssets.map(a => (
<tr key={a.id}>
<td>{a.id}</td>
<td>{a.name}</td>
</tr>
))
) : (
<tr>
<td colSpan={6}>No asset records found.</td>
</tr>
)}
</tbody>
</table>
</div>
</Fragment>
)
}
}https://stackoverflow.com/questions/55808645
复制相似问题