【问题标题】:React/Redux Application complete re-renders on changesReact/Redux 应用程序完成对更改的重新渲染
【发布时间】:2018-02-14 21:31:24
【问题描述】:

所以我正在开发一个在 React/Redux 中显示数据的项目。

通过 tcp 套接字接收数据并立即发送到存储区。 我的问题源于商店状态发生变化后立即重新渲染我的应用程序。

    function mapStateToProbs(state){
    return{
        ApplicationProcess: state.ApplicationProcess,
        SubSchedule: state.SubSchedule,
        Command: state.Command,
        CommandParameter: state.CommandParameter
    }
}

//pulling needed actions for dispatchign store
function mapDispachToProbs(dispatch){
    return bindActionCreators(actionCreators, dispatch)
}
    @connect(mapStateToProbs, mapDispachToProbs)
    @debugRender
    export default class Body extends React.Component{


        render(){
            //inline CSS block
            const divTable = {
                overflow: "auto",
                willChange: "transform",
                maxHeight: "20em"
            }

            const stayRight={
                float: "right"
            }

            //Basic Body with 3 Tables and their layout, passing down the data need to fill Tables
            return(
                <div className="container-fluid">
                    <div className="container-fluid"><Header hideCols={this.props.hideCols} subSchedule={this.props.SubSchedule} command={this.props.Command} applicationProcess={this.props.ApplicationProcess} /></div>
                    <div className="container-fluid"><Meta metadata = {this.props.CommandParameter}/></div>

                    <div className="container-fluid">
                        <div className="row">
                            <div className="col-md-9 col-sm-9">
                                <div className="row"><div className="col-md-10 text-center h5"> Sub-Schedules </div></div>
                                    <div className="row" style={divTable}>
                                        <Table tabledata={this.props.SubSchedule} sortTable={this.props.sortTable} />
                                    </div>
                                </div>
                            <div className="col-md-2 col-sm-10" style={stayRight}>
                                <div className="row"><div className="col-md-12 text-center h5">Enabled APIDs</div> </div>
                                    <div className="row" style={divTable}>
                                        <Table tabledata={this.props.ApplicationProcess} sortTable={this.props.sortTable} />
                                    </div>
                            </div>
                        </div>
                    </div>

                    <div className="container-fluid">
                        <div className="row">
                            <div className="col-md-12">
                                <div className="row"><div className="col-md-12 text-center h5">Commands</div></div>
                                <div className="row" style={divTable}>
                                    <Table tabledata={this.props.Command} sortTable={this.props.sortTable} />
                                </div>
                            </div>
                        </div>
                    </div>

                    <div className="container-fluid">
                        <div className="row">
                            <div className="col-md-9 col-sm-9">
                                <div className="row"><div className="col-md-10 text-center h5"> Sub-Schedules </div></div>
                                <div className="row" style={divTable}>
                                    <Tabledos tabledata={this.props.SubSchedule} sortTable={this.props.sortTable} />
                                </div>
                            </div>
                            <div className="col-md-2 col-sm-10" style={stayRight}>
                                <div className="row"><div className="col-md-12 text-center h5">Enabled APIDs</div> </div>
                                <div className="row" style={divTable}>
                                    <Tabledos tabledata={this.props.ApplicationProcess} sortTable={this.props.sortTable} />
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="container-fluid">
                        <div className="row">
                            <div className="col-md-12">
                                <div className="row"><div className="col-md-12 text-center h5">Commands</div></div>
                                <div className="row" style={divTable}>
                                    <Tabledos tabledata={this.props.Command} sortTable={this.props.sortTable} />
                                </div>
                            </div>
                        </div>
                    </div>

                </div>
                )

        }
    }

这是我的身体能力。不要奇怪我复制了这些表,因为前三个表在一个组件中完成所有事情。用我的 cols 创建 thead,用我的行创建 tbody 并管理关于我的表的所有内容。 我知道这不是反应的最佳实践,所以我进行了很多更改并将所有内容分离为组件。第二张表只有一个 TableHead 和 TableBody 组件:

@debugRender
export default class Table extends React.Component{
    render(){
        const { 
                tableHead,
                tableBody,
                DataType
                } = this.props.tabledata


        return(

                <table className="table table-bordered table-striped table-responsive">
                    <TableHead tableHead = {tableHead} DataType = {DataType}/>
                    <TableBody tableBody = {tableBody} />
                </table>
            )
    }


}

TableHead 将创建列:

export default class TableHead extends React.Component{

    constructor(props){
        super(props)

        this.state={
            columns: this.props.tableHead

        }
    }

    eachColumn(col, i){
        var uid = this.props.DataType + '_' + col,
            visibility = this.state.columns.byCol[col].visibility,
            col = visibility ?
                 <Columnn key={uid} id={uid} data={this.state.columns.byCol[col]}/> 
                : null

        return(
                col
            )
    }

    componentWillReceiveProps(nextProps){
        var arr = {...this.state.columns, ...nextProps.tableHead}
        //console.log(arr)
        this.setState({columns: arr})

    }
    shouldComponentUpdate(nextProps, nextState){
        if(this.props.tableHead.byCol !== nextProps.tableHead.byCol){
            console.log("return true")
            return true
        }
        console.log("return false")
        return false
    }

    render(){
        console.log(this.state)
        const{
            columns
        } = this.state
        return(
            <thead>
                <tr>
                    {columns.allCols.map(this.eachColumn.bind(this))}
                </tr>
            </thead>
        )
    }



}

而每一列基本上是这样的:

export default class Column extends React.Component{
    render(){
        const th = {
            backgroundColor: "#8c918d",
            width: "auto",
            whiteSpace: "nowrap"
        }
            return(
                <th id={this.props.id} 
                className="sticky-top" 
                style={th}>
                {this.props.data.name}
                </th>
            )
    }
}

如果我现在调度任何操作,例如将任何列的可见性设置为 false,不仅我的整个表格将重新渲染,我的正文和其中的所有其他组件也将重新渲染。那是我无法理解的。也许任何人都可以帮助我。

PS:欢迎提出关于使用 react/redux 时的最佳实践的任何建议。

编辑: 需要明确的是,我的视图中有 3 个表,我不想为同一任务执行 3 个单独的组件。由于所有表都将具有相同的选项,因此只有我显示的数据会发生变化。其他一切都应该相同。

【问题讨论】:

    标签: reactjs redux react-redux electron


    【解决方案1】:

    Redux 正在改变你的组件状态。当组件状态发生变化时(通过变化,不一定要有所不同),React 将重新渲染以验证 DOM 中是否有更新(他通过比较旧的虚拟 DOM 和新的虚拟 DOM 来做到这一点)他上马)。您可以优化返回 false 到 shouldComponentUpdate 的组件,这样做可以预先调用重新渲染:

    shouldComponentUpdate(nextProps, nextState) {
      return false;
    }
    

    但是,如果您的组件没有发生任何变化,您必须确切知道,否则 DOM 中的事情将失控。

    这就是你在 doc 中得到的所有东西来优化 React

    【讨论】:

    • 我真的不明白你的回答。我应该把 shouldCompenentUpdate return false 函数放在哪里?我知道我的组件会定期更新,所以返回默认 false 不是我想要的。
    • 是的,我知道。返回默认 false 永远不是解决方案。你必须比较一些你知道会改变的数据,如果改变了,你返回true,否则返回false。
    • 你检查了我的代码?这就是我正在做的事情。但问题是,我从 redux 商店获取道具的 body 组件每次都重新渲染。我以为我只是将道具传递给将获得更改的组件,并且只有那个会重新渲染。但它会重新渲染体内的所有内容。
    • 这是因为 props 是在 body 组件中连接的。所以你的身体组件有这个道具。当 redux 改变时,这个 props 会改变,所以 React 会重新渲染,即使你的组件不使用它(只是传递它)。例如,如果你有一个父组件到这个 body 组件,这个父组件不会被重新渲染,因为他与子 props 没有关系。
    • 好吧,我能理解。但现在我关于该主题的问题是:我的表最多可以有 5000 行,最多 20 列。我一次有 3 张桌子。所以我必须为每个表制作一个组件并单独连接它们?还是每个人都走得更远,创建一个组件并将其连接到我商店的更小部分?因为重新渲染 5000x20 html 元素似乎不是应该的工作方式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2020-11-27
    • 2018-03-24
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多