[英]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.