【问题标题】:React Grid - setState not triggering render in GridReact Grid - setState 未触发 Grid 中的渲染
【发布时间】:2019-06-16 17:40:57
【问题描述】:

这快把我逼疯了!我已经尝试了所有这些技巧来使用生命周期方法来渲染这些数据,以将道具数据与我的组件中的行数据的当前状态进行比较,但看起来可能带有行道具的 React Grid 没有更新,因为我可以看到控制台在我的控制台中记录带有数据的行。它有数据,但在我的表格中显示“无数据”,这意味着当我的表格呈现时,必须有“无数据”。现在,如果我对组件进行简单的更改,点击保存,它的更新和繁荣我在表中看到 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 代码中,如果我只是执行一行返回(或进行任何更改)并保存。组件更新。如此处所示,我将在控制台数组中渲染 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
);

【问题讨论】:

  • 你只在组件第一次挂载时调用getRows(),所以state.rowsprops.league不同步。尝试在 &lt;Grid ...&gt; 元素中直接使用 this.props.league
  • 我试过了。当我使用 &lt;Grid rows={this.props.league} columns={columns}&gt; 时,我得到“无数据”
  • 您能否在您的render() 函数中添加一个console.log(this.props.league) 并检查它在渲染时是否实际包含数据?
  • 我看到你从道具设置状态..你为什么不在构造函数中做呢?你在那里得到道具。这是相同的道具。
  • @MTCoster 我为道具添加了更新的图片。

标签: javascript reactjs devextreme


【解决方案1】:

所以这是一个艰难的教训。一直以来,我只是在我的 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 的基本原则,你应该创建新的状态位,你的 store 更新,这反过来会告诉连接的组件你有新的数据。我相信这种“连接”接线在我的情况下不起作用,因为我没有在减速器中创建/替换。所以我基本上把我在选择器中所做的一切(如上所示)移到我的减速器中,我正在使用 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;
    }

}

现在我连接的组件更新,我的数据加载到我的表中。基本上是因为Object.assign([], state) :)

【讨论】:

    猜你喜欢
    • 2017-01-29
    • 1970-01-01
    • 2018-09-22
    • 2021-12-08
    • 2021-11-09
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    相关资源
    最近更新 更多