繁体   English   中英

如何在同一反应组件中使用本地状态以及redux存储状态?

[英]How do I use local state along with redux store state in the same react component?

我有一个显示联系人的表,我想按名字对联系人排序。 contacts数组来自redux商店,然后来到道具,但我希望本地状态能够保存这些联系人的排序方式,因为它是本地UI状态。 我该如何实现这一目标? 到目前为止,我已将联系人放入componentWillReceiveProps但由于某些原因,它在更改时不会收到道具。 每次redux存储状态更改时,如何更新本地状态?

const Table = React.createClass({
  getInitialState () {
    return {contacts: []}
  },
  componentWillReceiveProps () {
    this.setState({ contacts: this.props.data.contacts})
  },
  sortContacts (parameter, e){
    ...
  },
  render () {
    return (
      <table>
        <thead>
          <tr>
            <th onClick={this.sortContacts.bind(this, "firstName")}>First Name</th>
          </tr>
        </thead>
        <tbody>
          {contactRows}
        </tbody>
      </table>
    )
  }
})

更新包含过滤的当前代码

import React, {Component} from 'react'
import TableRow from './TableRow'

class Table extends Component {
  constructor (props) {
    super(props)
    this.state = { sortBy: "fistName" }
  }
  sortContacts (parameter) {
    console.log('in sortContacts')

    this.setState({ sortBy: parameter })
  }
  sortedContacts () {
    console.log('in sortedContacts')

    const param = this.state.sortBy
    return (
      this.props.data.contacts.sort(function (a, b){
        if (!a.hasOwnProperty(param)){
          a[param] = " ";
        }
        if (!b.hasOwnProperty(param)){
          b[param] = " ";
        }
        const nameA = a[param].toLowerCase(), nameB = b[param].toLowerCase();
        if (nameA > nameB) {
          return 1;
        } else {
          return -1;
        }
      })
    )
  }
  filteredSortedContacts () {
    console.log('in filteredSortedContacts')

    const filterText = this.props.data.filterText.toLowerCase()
    let filteredContacts = this.sortedContacts()
    if (filterText.length > 0) {
      filteredContacts = filteredContacts.filter(function (contact){
        return (
          contact.hasOwnProperty('lastName') &&
          contact.lastName.toLowerCase().includes(filterText)
        )
      })
    }
    return filteredContacts
  }
  contactRows () {
    console.log('in contactRows')
    return this.filteredSortedContacts().map((contact, idx) =>
      <TableRow contact={contact} key={idx}/>
    )
  }
  render () {
    return (
      <div className="table-container">
        <table className="table table-bordered">
          <thead>
            <tr>
              <th className="th-cell" onClick={this.sortContacts.bind(this, "firstName")}>First Name</th>
              <th onClick={this.sortContacts.bind(this, "lastName")}>Last Name</th>
              <th>Date of Birth</th>
              <th>Phone</th>
              <th>Email</th>
              <th>Notes</th>
            </tr>
          </thead>
          <tbody>
            {this.contactRows()}
          </tbody>
        </table>
      </div>
    )
  }
}

export default Table

我现在看到的问题是contactRows, filteredSortedContacts, sortedContacts被多次调用,每个TableRow调用一次。 如果我只在体内调用一次contactRows我不知道这是怎么回事。

您使用redux存储和本地存储的方法是正确的。

只是不要尝试从组件中的redux store复制状态。 通过道具继续引用它。

而是创建一个sortedContacts函数,通过将本地存储的sortBy参数应用于redux存储的联系人来动态计算值。

const Table extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      sortBy: 'id' // default sort param
    }
  }

  sortContacts(param) {
    this.setState({ sortBy: param})
  }

  sortedContacts() {
    return this.props.contacts.sort(...); // return sorted collection
  }

  render() {
    return (
      <table>
        <thead>
          <tr>
            <th onClick={() => this.sortContacts("firstName")}>First Name</th>
          </tr>
        </thead>
        <tbody>
          {this.sortedContacts()}
        </tbody>
      </table>
    )
  }
}

不为初始渲染调用componentWillReceiveProps()方法。 如果您只打算使用来自props的数据作为初始数据,那么可以做的是:

getInitialState () {
  return {
    contacts: this.props.data.contacts
  }
}

React文档中,他们建议你将props命名为initialContacts,只是为了让道具真正清楚道具的唯一目的是在内部初始化内容。

现在,如果你想在this.props.contacts更改时更新它,你可以像使用的那样使用componentWillReceiveProps() 但我不确定这是最好的主意。 来自文档:

使用props在getInitialState中生成状态通常会导致“真实来源”的重复,即真实数据的位置。 这是因为只有在首次创建组件时才会调用getInitialState。

在可能的情况下,即时计算值以确保它们以后不会失去同步并导致维护问题。

React 16.3包含一个静态函数getDerivedStateFromProps(nextProps, prevState) ,它将在初始挂载后以及接收到新的props时调用。 请参阅https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM