sta*_*lei 14 javascript state reactjs redux react-redux
我有一个显示联系人的表,我想按名字对联系人排序.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>
)
}
})
Run Code Online (Sandbox Code Playgroud)
更新包含过滤的当前代码
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
Run Code Online (Sandbox Code Playgroud)
我现在看到的问题contactRows, filteredSortedContacts, sortedContacts是被多次调用,每个TableRow调用一次.如果我只是contactRows在体内打一次,我不明白这是怎么回事.
Mic*_*jbe 10
您使用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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
componentWillReceiveProps()初始渲染不会调用该方法。如果您只想使用 props 中的数据作为初始数据,可以执行以下操作:
getInitialState () {
return {
contacts: this.props.data.contacts
}
}
Run Code Online (Sandbox Code Playgroud)
在React 文档中,他们建议您将 props 命名为initialContacts,只是为了清楚地表明 props 的唯一目的是在内部初始化某些内容。
现在,如果您希望它在this.props.contacts更改时更新,您可以componentWillReceiveProps()像以前一样使用。但我不确定这是最好的主意。来自文档:
使用 props 在 getInitialState 中生成状态通常会导致“事实来源”的重复,即真实数据的位置。这是因为 getInitialState 仅在首次创建组件时调用。
只要有可能,即时计算值,以确保它们以后不会不同步并导致维护麻烦。
| 归档时间: |
|
| 查看次数: |
13465 次 |
| 最近记录: |