代码之家  ›  专栏  ›  技术社区  ›  geostocker

React setState不更改特定属性的状态

  •  3
  • geostocker  · 技术社区  · 7 年前

    我现在公司的一个老开发人员最近把尾巴夹在两腿之间,在不得不做打字脚本/反应后逃跑了,当我看到一堆坏代码时就离开了我。

    我现在的问题是,我有一个TypeScript代码,它只是从数组中删除一个项并更改状态:

    var currentFiles = this.state.openFiles;
        var index = this.state.openFiles.findIndex((f: IFileModel) => f.fileId == fileId)
        currentFiles.splice(index, 1);
        this.setState({ 
            mode: "gallery",
            openFiles: currentFiles 
        }, () => console.log(this.state.mode));
    

    我的问题是,国家从来没有更新 mode ,即使设置状态 应该 这样做。不管我怎么改变现状 console.log 0

    即使在render函数中放置一个断点,也会显示 模式 0 "gallery"

    这是初始状态:

    this.state = {
                openFiles: [],
                mode: "gallery",
                categories: [],
                galleryState: {}
            }
    

    有什么建议吗?

    1 回复  |  直到 7 年前
        1
  •  7
  •   T.J. Crowder    7 年前

    你在评论中说你被一个刚离开公司的开发人员留下了这段代码。恐怕他们给你留下了违反React两条规则的代码:-)

    1. 不能直接修改状态,包括 this.state currentFiles.splice(index, 1) .

    2. 您正在基于现有状态设置新状态,但不使用的回调形式 setState .

    // Use the callback form that receives the up-to-date state as a parameter.
    this.setState(
        ({openFiles}) => {
            var index = openFiles.findIndex((f: IFileModel) => f.fileId == fileId)
            // (Do you need an `if (index !== -1)` check here?)
            // Create a *new* array without the entry
            var currentFiles = [...openFiles.slice(0, index), ...openFiles.slice(index+1)];
            // Return the new state
            return {
                mode: "gallery",
                openFiles: currentFiles 
            };
        },
        () => console.log(this.state.mode)
    );
    

    the state docs .

    实例:

    class Example extends React.Component {
        constructor(...args) {
            super(...args);
            this.removeFileOnClick = this.removeFileOnClick.bind(this);
            this.state = {
                mode: "main",
                openFiles: [
                    {fileId: 1, name: "File 1"},
                    {fileId: 2, name: "File 2"},
                    {fileId: 3, name: "File 3"},
                    {fileId: 4, name: "File 4"},
                    {fileId: 5, name: "File 5"}
                ]
            };
        }
    
        removeFileOnClick(e) {
            const fileId = e.currentTarget.getAttribute("data-id");
            this.setState(
                ({openFiles}) => {
                    var index = openFiles.findIndex((f) => f.fileId == fileId)
                    // (Do you need an `if (index !== -1)` check here?)
                    // Create a *new* array without the entry
                    var currentFiles = [...openFiles.slice(0, index), ...openFiles.slice(index+1)];
                    // Return the new state
                    return {
                        mode: "gallery",
                        openFiles: currentFiles 
                    };
                },
                () => console.log(this.state.mode)
            );
        }
    
        render() {
            return ( 
                <div>
                    Mode: {this.state.mode}
                    <div>
                        OpenFiles ({this.state.openFiles.length}):
                        <div>{this.state.openFiles.map(file =>
                            <div><button data-id={file.fileId} onClick={this.removeFileOnClick}>X</button>{file.name}</div>
                        )}</div>
                    </div>
                </div>
            );
        }
    }
    
    ReactDOM.render(
        <Example />,
        document.getElementById("root")
    );
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>

    旁注:如果您不喜欢这里的双排列:

    var currentFiles = [...openFiles.slice(0, index), ...openFiles.slice(index+1)];
    

    你可以这样做:

    var currentFiles = openFiles.slice();
    currentFiles.splice(index, 1);
    
    推荐文章