React Grid - setState 不触发 Grid 中的渲染
React Grid - setState not triggering render in Grid
这让我抓狂!我已经尝试了所有这些技巧来使用生命周期方法来渲染这些数据,以将道具数据与我组件中行数据的当前状态进行比较,但似乎带有行道具的 React Grid 没有更新,因为我可以看到控制台在我的控制台中记录包含数据的行。它有数据,但它在我的 table 中显示 'no data',这意味着当我的 table 呈现时,肯定有 'no data'。现在,如果我对组件进行简单的更改,点击保存,它的更新和繁荣我在 table 中看到 3 个条目。奇怪的是现在我的控制台数组中有 6 个条目。
export default class Demo extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'teamName', title: 'Team' },
{ name: 'profilePic', title: 'Avatar' },
{ name: 'score', title: 'Score' },
{ name: 'profileName', title: 'profileName' },
{ name: '', title: 'Rank' }
],
rows: [],
pageSizes: [5, 10, 15],
currentPage: 0,
loading: true,
counter: 0
};
}
componentWillMount() {
this.getRows();
}
componentDidMount() {
this.getRows();
}
getRows = () => {
this.setState({
rows: this.props.league
});
};
// static getDerivedStateFromProps(props, state) {
// if (props.league.length !== state.rows.length) {
// return {
// rows: props.league
// };
// }
// return null;
// }
// componentDidMount() {
// console.log("NP1::",this.props.league)
// this.setState({rows: this.props.league})
// }
// componentDidUpdate(nextProps, prevState) {
// if(nextProps.league!==prevState.rows){
// //Perform some operation here
// console.log("NP2::",this.props.league)
// this.setState({rows: this.props.league});
// this.classMethod();
// }
// }
// static getDerivedStateFromProps(nextProps, prevState){
// if(nextProps.league!==prevState.rows){
// console.log("NP::",nextProps.league)
// return{
// rows: nextProps.league
// }
// return
// }
// else return null;
// }
// componentDidUpdate(nextProps, prevState) {
// if(nextProps.league!==prevState.rows){
// //Perform some operation here
// console.log("NP2::",this.props.league)
// this.setState({rows: this.props.league});
// this.classMethod();
// }
// }
// componentWillReceiveProps(nextProps) {
// console.log("NP::",nextProps.league+"----"+this.props.league);
// if (nextProps.league !== this.props.league) {
// console.log("NP2::",nextProps.league)
// this.setState({rows: nextProps.league})
// }
// }
// componentWillUpdate(nextProps, nextState) {
// console.log("NP::", nextProps.league + "----" + this.state.rows);
// if (nextProps.league !== this.state.rows) {
// this.setState({ rows: nextProps.league })
// }
// }
render() {
const { rows, columns } = this.state;
console.log("STATEDATA::", this.state)
return (
<Paper>
<Grid
rows={rows}
columns={columns}
>
<RowDetailState />
<Table
cellComponent={Cell}
/>
<TableHeaderRow />
<TableRowDetail
contentComponent={RowDetail}
/>
</Grid>
{/* <PagingPanel /> */}
</Paper>
);
}
}
我留在了注释代码中,这样你就可以看到我玩过的 LF 方法。这是没有数据的第一个渲染图和包含行的状态数据的控制台日志。
我的行的初始状态是 [] 所以我们知道 setState 发生了。为什么不触发此组件中的渲染。我在 Ag Grid 上看到了一些关于此的帖子,但是 React 网格是否存在任何已知问题并使其正确呈现?
如前所述,在 Vs 代码中,如果我只执行一行 return(或进行任何更改)并保存。组件更新。如此处所示,我将在控制台数组中呈现 3 个条目和 6 个条目。
添加此内容以便您可以同时查看状态联赛道具。
这里是父组件
class LeaguePage extends Component {
static propTypes = {
loadLeague: PropTypes.func.isRequired,
}
constructor(props) {
super(props)
this.state = {
};
}
componentWillMount() {
this.props.loadLeague();
}
render() {
console.log("LEAGUEPROPS::",this.props);
return (
<div className="g-row">
<div className="g-col">
<h1>LeaguePage</h1>
{/* <LeagueTable {...this.props} /> */}
<br />
<br />
<RgDetail {...this.props} rows={this.state.rows} />
<br />
<br />
{/* <RgTable /> */}
<br />
<br />
<br />
</div>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
console.log("MYSTATE::",state)
return {
league: LeagueSelector(state),
}
}
const mapDispatchToProps = Object.assign(
{},
leagueActions
);
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(LeaguePage));
联赛的选择器
import { createSelector } from 'reselect';
import _ from 'lodash';
var data = [];
export function getLeague(state) {
if (state.league) {
return state.league;
}
}
function transform(UserRecord) {
const outerObj = UserRecord[Object.keys(UserRecord)[0]];
data.push(outerObj);
return data
}
export function getSortedLeague(state) {
if (state.length > 1) {
state.map(x => transform(x));
return data;
}
else
return data;
}
//=====================================
// MEMOIZED SELECTORS
//-------------------------------------
export const LeagueSelector = createSelector(
getLeague,
getSortedLeague
);
所以这是一次惨痛的教训。一直以来,我只是在我的 reducer 中返回可能的有效载荷(而不是用新状态替换状态),然后在选择器中(见上文)我从中导出了一个新的状态位。我想你可以说是错误的模式或做法。我迷失了自己,试着去了解我对选择器的使用。
我的旧减速器看起来像
const user = [{
UID: {
Key: {
profileName: '',
profilePic: '',
score: 0,
teamKeysTier1: '',
teamKeysTier2: '',
teamName: '',
uid: ''
}
}
}];
export function leagueReducer(state = user, {payload, type}) {
switch (type) {
case LOAD_LEAGUE_SUCCESS:
console.log("REDPAYLOAD::",payload)
return payload;
default:
return state;
}
}
我基本上忘记了 reducer 的基本原则,你应该在其中创建新的状态位,你的存储更新,这反过来会告诉连接的组件你有新数据。我相信这种 'connected' 接线在我的情况下不起作用,因为我没有 creating/replace 在我的减速器中。所以我基本上把我在我的选择器中所做的一切(见上图),将它移到我的减速器中,我正在使用 Object.Assign 创建一个新的状态片段(我知道它有点简洁但现在我“简洁明了)
这是我的新减速器。
import { LOAD_LEAGUE_SUCCESS } from '../actions/actionTypes';
const user = [{
profileName: 'FEKing',
profilePic: '',
score: 100,
teamKeysTier1: '',
teamKeysTier2: '',
teamName: 'TheCreator',
uid: ''
}];
export function leagueReducer(state = user, {payload, type}) {
switch (type) {
case LOAD_LEAGUE_SUCCESS:
payload.map(x => {
const outObj = x[Object.keys(x)[0]];
state.push(outObj);
})
console.log("user::",state)
return Object.assign([], state);
default:
return state;
}
}
现在我的连接组件更新了,我的数据加载到我的 table 中。基本上是因为 Object.assign([], state)
:)
这让我抓狂!我已经尝试了所有这些技巧来使用生命周期方法来渲染这些数据,以将道具数据与我组件中行数据的当前状态进行比较,但似乎带有行道具的 React Grid 没有更新,因为我可以看到控制台在我的控制台中记录包含数据的行。它有数据,但它在我的 table 中显示 'no data',这意味着当我的 table 呈现时,肯定有 'no data'。现在,如果我对组件进行简单的更改,点击保存,它的更新和繁荣我在 table 中看到 3 个条目。奇怪的是现在我的控制台数组中有 6 个条目。
export default class Demo extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
columns: [
{ name: 'teamName', title: 'Team' },
{ name: 'profilePic', title: 'Avatar' },
{ name: 'score', title: 'Score' },
{ name: 'profileName', title: 'profileName' },
{ name: '', title: 'Rank' }
],
rows: [],
pageSizes: [5, 10, 15],
currentPage: 0,
loading: true,
counter: 0
};
}
componentWillMount() {
this.getRows();
}
componentDidMount() {
this.getRows();
}
getRows = () => {
this.setState({
rows: this.props.league
});
};
// static getDerivedStateFromProps(props, state) {
// if (props.league.length !== state.rows.length) {
// return {
// rows: props.league
// };
// }
// return null;
// }
// componentDidMount() {
// console.log("NP1::",this.props.league)
// this.setState({rows: this.props.league})
// }
// componentDidUpdate(nextProps, prevState) {
// if(nextProps.league!==prevState.rows){
// //Perform some operation here
// console.log("NP2::",this.props.league)
// this.setState({rows: this.props.league});
// this.classMethod();
// }
// }
// static getDerivedStateFromProps(nextProps, prevState){
// if(nextProps.league!==prevState.rows){
// console.log("NP::",nextProps.league)
// return{
// rows: nextProps.league
// }
// return
// }
// else return null;
// }
// componentDidUpdate(nextProps, prevState) {
// if(nextProps.league!==prevState.rows){
// //Perform some operation here
// console.log("NP2::",this.props.league)
// this.setState({rows: this.props.league});
// this.classMethod();
// }
// }
// componentWillReceiveProps(nextProps) {
// console.log("NP::",nextProps.league+"----"+this.props.league);
// if (nextProps.league !== this.props.league) {
// console.log("NP2::",nextProps.league)
// this.setState({rows: nextProps.league})
// }
// }
// componentWillUpdate(nextProps, nextState) {
// console.log("NP::", nextProps.league + "----" + this.state.rows);
// if (nextProps.league !== this.state.rows) {
// this.setState({ rows: nextProps.league })
// }
// }
render() {
const { rows, columns } = this.state;
console.log("STATEDATA::", this.state)
return (
<Paper>
<Grid
rows={rows}
columns={columns}
>
<RowDetailState />
<Table
cellComponent={Cell}
/>
<TableHeaderRow />
<TableRowDetail
contentComponent={RowDetail}
/>
</Grid>
{/* <PagingPanel /> */}
</Paper>
);
}
}
我留在了注释代码中,这样你就可以看到我玩过的 LF 方法。这是没有数据的第一个渲染图和包含行的状态数据的控制台日志。
我的行的初始状态是 [] 所以我们知道 setState 发生了。为什么不触发此组件中的渲染。我在 Ag Grid 上看到了一些关于此的帖子,但是 React 网格是否存在任何已知问题并使其正确呈现?
如前所述,在 Vs 代码中,如果我只执行一行 return(或进行任何更改)并保存。组件更新。如此处所示,我将在控制台数组中呈现 3 个条目和 6 个条目。
添加此内容以便您可以同时查看状态联赛道具。
这里是父组件
class LeaguePage extends Component {
static propTypes = {
loadLeague: PropTypes.func.isRequired,
}
constructor(props) {
super(props)
this.state = {
};
}
componentWillMount() {
this.props.loadLeague();
}
render() {
console.log("LEAGUEPROPS::",this.props);
return (
<div className="g-row">
<div className="g-col">
<h1>LeaguePage</h1>
{/* <LeagueTable {...this.props} /> */}
<br />
<br />
<RgDetail {...this.props} rows={this.state.rows} />
<br />
<br />
{/* <RgTable /> */}
<br />
<br />
<br />
</div>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
console.log("MYSTATE::",state)
return {
league: LeagueSelector(state),
}
}
const mapDispatchToProps = Object.assign(
{},
leagueActions
);
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(LeaguePage));
联赛的选择器
import { createSelector } from 'reselect';
import _ from 'lodash';
var data = [];
export function getLeague(state) {
if (state.league) {
return state.league;
}
}
function transform(UserRecord) {
const outerObj = UserRecord[Object.keys(UserRecord)[0]];
data.push(outerObj);
return data
}
export function getSortedLeague(state) {
if (state.length > 1) {
state.map(x => transform(x));
return data;
}
else
return data;
}
//=====================================
// MEMOIZED SELECTORS
//-------------------------------------
export const LeagueSelector = createSelector(
getLeague,
getSortedLeague
);
所以这是一次惨痛的教训。一直以来,我只是在我的 reducer 中返回可能的有效载荷(而不是用新状态替换状态),然后在选择器中(见上文)我从中导出了一个新的状态位。我想你可以说是错误的模式或做法。我迷失了自己,试着去了解我对选择器的使用。
我的旧减速器看起来像
const user = [{
UID: {
Key: {
profileName: '',
profilePic: '',
score: 0,
teamKeysTier1: '',
teamKeysTier2: '',
teamName: '',
uid: ''
}
}
}];
export function leagueReducer(state = user, {payload, type}) {
switch (type) {
case LOAD_LEAGUE_SUCCESS:
console.log("REDPAYLOAD::",payload)
return payload;
default:
return state;
}
}
我基本上忘记了 reducer 的基本原则,你应该在其中创建新的状态位,你的存储更新,这反过来会告诉连接的组件你有新数据。我相信这种 'connected' 接线在我的情况下不起作用,因为我没有 creating/replace 在我的减速器中。所以我基本上把我在我的选择器中所做的一切(见上图),将它移到我的减速器中,我正在使用 Object.Assign 创建一个新的状态片段(我知道它有点简洁但现在我“简洁明了)
这是我的新减速器。
import { LOAD_LEAGUE_SUCCESS } from '../actions/actionTypes';
const user = [{
profileName: 'FEKing',
profilePic: '',
score: 100,
teamKeysTier1: '',
teamKeysTier2: '',
teamName: 'TheCreator',
uid: ''
}];
export function leagueReducer(state = user, {payload, type}) {
switch (type) {
case LOAD_LEAGUE_SUCCESS:
payload.map(x => {
const outObj = x[Object.keys(x)[0]];
state.push(outObj);
})
console.log("user::",state)
return Object.assign([], state);
default:
return state;
}
}
现在我的连接组件更新了,我的数据加载到我的 table 中。基本上是因为 Object.assign([], state)
:)