如何在同一个 React 组件中使用本地状态和 redux 存储状态? [英] How do I use local state along with redux store state in the same react component?

查看:23
本文介绍了如何在同一个 React 组件中使用本地状态和 redux 存储状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

const Table = React.createClass({getInitialState() {返回{联系人:[]}},componentWillReceiveProps(){this.setState({ 联系人: this.props.data.contacts})},sortContacts(参数,e){...},使成为 () {返回 (<表格><头><tr><th onClick={this.sortContacts.bind(this, "firstName")}>名字</th></tr></thead>{联系行}</tbody>)}})

更新当前代码,包括过滤

import React, {Component} from 'react'从 './TableRow' 导入 TableRow类表扩展组件{构造函数(道具){超级(道具)this.state = { sortBy: "fistName" }}sortContacts(参数){console.log('在 sortContacts')this.setState({ sortBy: 参数})}排序的联系人(){console.log('in sortedContacts')const 参数 = this.state.sortBy返回 (this.props.data.contacts.sort(function (a, b){如果 (!a.hasOwnProperty(param)){[参数] = " ";}如果 (!b.hasOwnProperty(param)){b[参数] = " ";}const nameA = a[param].toLowerCase(), nameB = b[param].toLowerCase();如果(名称A>名称B){返回 1;} 别的 {返回-1;}}))}过滤的SortedContacts(){console.log('在已过滤的SortedContacts')const filterText = this.props.data.filterText.toLowerCase()让filteredContacts = this.sortedContacts()如果 (filterText.length > 0) {过滤的联系人 = 过滤的联系人.过滤器(功能(联系){返回 (contact.hasOwnProperty('lastName') &&contact.lastName.toLowerCase().includes(filterText))})}返回已过滤的联系人}联系行(){console.log('in contactRows')返回 this.filteredSortedContacts().map((contact, idx) =><TableRow contact={contact} key={idx}/>)}使成为 () {返回 (<div className="table-container"><table className="table table-bordered"><头><tr><th className="th-cell" onClick={this.sortContacts.bind(this, "firstName")}>名字</th><th onClick={this.sortContacts.bind(this, "lastName")}>Last Name</th><th>出生日期</th><th>电话</th><th>电子邮件</th><th>注释</th></tr></thead>{this.contactRows()}</tbody>

)}}导出默认表

我现在看到的问题是 contactRows、filteredSortedContacts、sortedContacts 被多次调用,每个 TableRow 调用一次.如果我只在正文中调用一次 contactRows,我看不出这是怎么发生的.

解决方案

您同时使用 redux 存储和本地存储的方法是正确的.

不要尝试从组件中的 redux 存储中复制状态.继续通过 props 引用它.

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

const 表扩展了 React.Component {构造函数(道具){超级(道具);this.state = {sortBy: 'id'//默认排序参数}}sortContacts(参数){this.setState({ sortBy: param})}排序的联系人(){返回 this.props.contacts.sort(...);//返回排序后的集合}使成为() {返回 (<表格><头><tr><th onClick={() =>this.sortContacts("firstName")}>名字</th></tr></thead>{this.sortedContacts()}</tbody>)}}

I have a table that displays contacts and I want to sort the contacts by first name. The contacts array comes from the redux store, which will come then come through the props, but I want the local state to hold how those contacts are sorted, since it's local UI state. How do I achieve this? I so far have placed contacts into componentWillReceiveProps but for some reason it doesn't receive the props when it changes. How do I update the local state each time the redux store state changes?

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>
    )
  }
})

update of current code that includes filtering

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

The issue I'm seeing now is that contactRows, filteredSortedContacts, sortedContacts are being called multiple times, once for each TableRow. I don't see how this can be happening if I'm only calling contactRows once in the body.

解决方案

Your approach to use both redux store and local store is correct.

Just do not try to duplicate the state from redux store in your component. Keep referring to it via props.

Instead create a sortedContacts function that computes value on the fly by applying locally-stored sortBy param to redux-stored contacts.

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>
    )
  }
}

这篇关于如何在同一个 React 组件中使用本地状态和 redux 存储状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆