我有一个显示联系人的表格,我想按名字对联系人进行排序。 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
一次,我就不知道如何发生这种情况。
答案 0 :(得分:8)
您使用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>
)
}
}
答案 1 :(得分:3)
不会为初始渲染调用componentWillReceiveProps()
方法。如果您只打算使用props中的数据作为初始数据,那么可以做的是:
getInitialState () {
return {
contacts: this.props.data.contacts
}
}
在React docs中,他们建议你将道具命名为initialContacts,只是为了让道具的唯一目的是在内部初始化内容。
现在,如果您希望在this.props.contacts
更改时更新,则可以像使用componentWillReceiveProps()
一样使用<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>:jQuery Attribute:</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<style>
.one {font-size:20px;}
.second {color:red;}
</style>
<script src="js/jquery-1.11.3.min.js"></script>
</head>
<body>
<h2>All jQuery Attribute</h2>
<p class="one">First Para </p>
<p class="one">Second Para </p>
<p class="one">Third Para </p>
<p class="one">Fourth Para </p>
<p class="one">Fifth Para </p>
<script>
$('p:nth-child(1)').addClass('second');
</script>
</body>
</html>
。但我不确定这是最好的主意。来自文档:
使用props在getInitialState中生成状态通常会导致 重复“真相来源”,即真实数据所在的地方。这是 因为只有在第一个组件时才会调用getInitialState 创建
尽可能即时计算值以确保它们不会 稍后会失去同步并导致维护问题。
答案 2 :(得分:2)
React 16.3包含一个静态函数ano2015.groupby("UO_Ajustada").Empenhado.agg(['sum','count'])
,它将在初始挂载后以及收到新道具时调用。见https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops