首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在呈现组件时不填充状态数组?

为什么在呈现组件时不填充状态数组?
EN

Stack Overflow用户
提问于 2019-04-23 09:57:26
回答 3查看 50关注 0票数 0

我已经创建了一个组件来对HTML表进行排序和筛选。该功能是正确的,但我的表呈现"No“时遇到了一个问题。但是当我单击其中一个标头时,它将显示数据数组的内容处于状态。我真的对这种奇怪的行为感到困惑和困惑。我认为问题可能与filterAssets函数有关,因为如果我从以下内容中更改:

代码语言:javascript
复制
let filterAssets = this.state.data.filter(a => {
  return a.name.toLowerCase().indexOf(this.state.search) !== -1
})

对此:

代码语言:javascript
复制
let filterAssets = this.props.assetManagement.filter(a => {
  return a.name.toLowerCase().indexOf(this.state.search) !== -1
})

这是下面的代码,如果有帮助的话

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

发布于 2019-04-23 10:09:32

filterAssets != 0更改为filterAssets.length > 0

第一次渲染:

代码语言:javascript
复制
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是绝对错误的,所以请先修改这一行。

票数 0
EN

Stack Overflow用户

发布于 2019-04-23 10:32:32

在不使用构造函数的情况下,对React组件使用替代语法时,您就不能再访问道具。因此,如果重新使用标准构造函数,问题就会消失,例如:

代码语言:javascript
复制
constructor(props) {
    super(props);
    this.state = {
      name: "",
      search: "",
      data: this.props.assetManagement
    };

    this.sortBy = this.sortBy.bind(this);
    this.compareBy = this.compareBy.bind(this);
  }
票数 0
EN

Stack Overflow用户

发布于 2019-04-23 10:43:38

这里真正的问题是,您有两个数据源:state.dataprops.assetManagement --从redux检索并从props.assetManagement获取最新数据,但是当需要触发排序时,可以复制到state.data。然后就会出现问题,因为在触发props.assetManagement函数之前,您不会从state.data复制到sortBy

解决方案是摆脱state.data并将排序键存储在状态中。您可以更新、重置该键值,并且排序逻辑仅适用于props.assetManagement

代码语言:javascript
复制
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://codesandbox.io/s/n91pq7073l

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55808645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档