簡體   English   中英

React setState不改變特定屬性的狀態

[英]React setState not changing state of particular property

我現在公司的一個舊開發人員最近把他的尾巴放在他的腿之間,並且在做了打字稿/反應后逃離,留下了一堆破碎的代碼。

我現在的問題是我有這個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 ,即使setState 應該這樣做。 無論我如何改變, console.log顯示為0

即使在渲染函數中放置斷點,也會向我顯示mode0 ,它應該是"gallery"

這是初始狀態:

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

有什么建議?

您在評論中說,您最近離開了該公司的開發人員已離開此代碼。 我擔心他們給你的代碼違反了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)
);

更多在州文件

實例:

 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM