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

对视图中未显示的反应组件的更改-一个字符的更改显示在onChange中

  •  0
  • geostocker  · 技术社区  · 6 年前

    问题:

    我似乎无法更改输入标记中的占位符(内部 <Details /> ).

    预期行为:

    输入标记将使用组件的状态及其 handleChange 功能。

    实际行为: ( 很抱歉搞得一团糟,这项工作正在进行中! )

    对输入字段所做的更改仅注册一个字符。

    例子 : 已选择中的所有字符 FileName 删除它们会在 console.log() 手摇 功能。但是,该字段在视图上从未更改,但具有相同的值。

    我试过的:

    我试过用 props state 来处理这些变化,但没什么用。我想我可能得像对待 FileItem ,但我不确定。

    实际代码:

    import * as React from "react";
    import { IFileModel, IFileWrapper } from "../models/fileModel";
    import { Fortress } from "../../dependencies/fortress";
    
    let divStyle = {
        width: "50px",
        border: "1px solid #000",
        padding: "5px",
        margin: "5px"
    };
    
    declare let config : {[key : string] : string};
    
    const $F = new Fortress(config);
    
    export class DetailsPanel extends React.Component<IFileModel, any> {
        constructor(props : IFileModel) {
            super(props); 
            this.state = { 
                isDisplayed : false 
            };
            this.toggle = this.toggle.bind(this);  
        }  
    
        toggle() {
            let newIsCollapsed = !(this.state.isDisplayed);
            this.setState({ isDisplayed : newIsCollapsed })
        }   
    
        render() {
            return(
                <div>
                    <div>
                        <input className="button" type="submit" value={ (!this.state.isDisplayed) ? "Show Panel" : "Hide Panel" } onClick={this.toggle} />
                    </div>
                    { this.state.isDisplayed ? <Details {...this.props} /> : null }
                </div>
            );
        }
    }
    
    export class Details extends React.Component <IFileModel, any> {
    
        constructor(props : IFileModel) {
            super(props);
            this.state = {
                currentFile : this.props
            };
            this.onSubmit = this.onSubmit.bind(this);
            this.handleChange = this.handleChange.bind(this);
        }
        // http://localhost/admin/shared/file/SaveFile/?
        /*
            FileId: 1
            FileName: shirt.pdf
            LCID: 2057
            FileVariation: 0
            DisplayName: shirt.png
            OriginalFileName: shirt__1_3_2057.pdf
            CategoryId: 0
            FileType: 1
            FileExtension: png
            FileSize: 419920
            Width: 615
            Height: 462
            FileData: 
            AllowedVariantTypes: 0
            RequireAuthorization: 0
            AdminId: 1
            CreationDate: /Date(1450692426023)/
            ModifyDate: /Date(1450692426023)/
            ExpiryDate: /Date(253402300799997)/
        */
    
        handleChange(e : any) { 
            console.log(e.target.name, e.target.value);
            this.setState({ [e.target.name] : e.target.value });
        }
    
        onSubmit() {
            const state = this.state.currentFile;
            console.log($F.writeAdminUrl("shared", "file", "SaveFile"));
            console.log(JSON.stringify(state));
            // fetch($F.writeAdminUrl("shared", "file", "SaveFile"), {
            //     method: "POST",
            //     headers: {
            //         "credentials": "same-origin", 
            //         "mode": "no-cors",
            //         "Content-Type" : "application/json"
            //     },
            //     body : JSON.stringify({ fileId : state.fileId })
            // })
        }
    
        render() {
            const currentFile = this.props;
            return(
                <div style={{border: "1px dashed black", padding: "4px"}}>
                    <div>
                        <p> File Name: </p>
                        <input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
                    </div>
                    <div>
                        <p> Image: </p>
                        <input type="text" value={currentFile.imageUrl} name="imageUrl" onChange={this.handleChange} />
                    </div>
                    <div>
                        <p> Creation date: </p>
                        <input type="text" value={currentFile.creationDate} name="creationDate" onChange={this.handleChange} />
                    </div>
                    <div>
                        <p> LCID: </p>
                        <input type="text" name="LCID" value={currentFile.LCID} onChange={this.handleChange} />
                    </div>
                    <div>
                        <input onClick={(currentFile) ? this.onSubmit : null} type="submit"/>
                    </div>
                </div>
            );
        }
    }
    
    export class FileItem extends React.Component<IFileModel> {
    
        constructor(props : IFileModel) {
            super(props);
            this.onSelect = this.onSelect.bind(this);
        }
    
        onSelect() {
            this.props.onSelect(this.props); 
        }
    
        render() {
            return (
                <div className="fileItem" style={{ width: "100px", height: '150px', float: 'left' }} onClick={this.onSelect}>
                    <img src={"http://localhost/content/image/" + this.props.imageUrl} style={divStyle} />
                    {this.props.fileName}
                    <button className="edit" />
                </div>
            );
        } 
    }
    
    export class FileList extends React.Component<any, any> {
    
        constructor(props : any) {
            super(props);
            this.state = { files: [], skip: 0, take: 10 }
            this.increaseTake = this.increaseTake.bind(this);
            this.onSelect = this.onSelect.bind(this);
        }
    
        getImages(skip : number, take : number, shouldAdd : boolean) {
    
    
            var that = this;
            fetch("http://localhost/admin/shared/file/GetImages?take=" + take + "&skip=" + skip + "&FileType=0&_2331223a3543as", {
                credentials: "same-origin", mode: "no-cors"
            })
                .then(function(response) {
                    return response.json();
                })
                .then(function (results) {
                    var newFiles = results.data.map((file : any) => ({
                        imageUrl: file.OriginalFileName,
                        fileName: file.DisplayName,
                        fileId: file.FileId,
                        creationDate: file.CreationDate,
                        LCID: file.LCID
                    }));
    
                    if (shouldAdd) {
                        newFiles = that.state.files.concat(newFiles);
                    }
    
                    that.setState({ files: newFiles });
    
                });
        }
    
        onSelect(file : IFileModel) { 
            this.props.onFileSelected(file);
        }
    
        increaseTake() {
            var currentSkip = this.state.skip + 10;
            this.setState({ skip: currentSkip });
            this.getImages(currentSkip, this.state.take, true);
        }
    
        componentWillMount() {
            // perfom ajax call
            this.getImages(0, this.state.take, true);
        }
    
    
        render() {
    
            return (<div>
    
                {this.state.files.map((item: IFileModel, index: number) =>
                    <FileItem key={index} {...item} onSelect={this.onSelect} />
                    )
                }
                <div style={{ clear: 'both' }}></div>
                <div onClick={this.increaseTake}>take more</div>
            </div>)
        }
    }
    
    export class FileGallery extends React.Component <any, any> {
        constructor(props : any) {
            super(props);
            let fm : IFileModel;
            this.state = {
                sidebarCollapsed : false,
                selectedFile : fm
            }; 
    
            this.onFileSelected = this.onFileSelected.bind(this);
        }
    
        onFileSelected(file : IFileModel) {
            this.setState({ selectedFile : file }); 
        }
    
        render() {
            const selectedFile = this.state.selectedFile;
            return (
                <div>
                    <div className="FileGalleryHeader">
                        <div>Galley</div>
                        <div>Upload</div>
                    </div>
                    <div className="FileGalleyMain" style={{ width: "80%", display : 'block', height:"400px", overflow : "auto", float : "left"}}>
                        <FileList onFileSelected={this.onFileSelected}/>
                    </div>
                    <div style={{ width: "20%", display: "block", float : "right", height: "800px"}}>
                        <DetailsPanel {...selectedFile} onSubmit={(selectedFile) ? selectedFile.onSubmit : null } />
                    </div>
            </div>);
        }
    }
    

    型号:

    export interface IFileModel {
        fileId: number;
        fileName: string;
        categoryId: number;
        fileType: number;
        fileExtension: string;
        fileSize: string;
        width: number;
        height: number;
        creationDate: string;
        imageUrl: string;
        LCID: string;
        onSubmit: Function;
        onSelect: Function; 
    }
    
    export interface IFileWrapper {
        file: IFileModel;   
    } 
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   xcatliu    6 年前

    就我查看的代码而言,它可能有两个问题:

    一。你在设置一个错误的状态 Details

    handleChange(e : any) { 
        console.log(e.target.name, e.target.value);
        this.setState({ [e.target.name] : e.target.value });
    }
    

    这应该是:

    handleChange(e : any) { 
        console.log(e.target.name, e.target.value);
        this.setState({ currentFile: {
            ...this.state.currentFile,
            [e.target.name]: e.target.value
        });
    }
    

    2。你不应该设置任何 props 作为 input 价值,应该是 state 相反

        const currentFile = this.props;
        return(
            <div style={{border: "1px dashed black", padding: "4px"}}>
                <div>
                    <p> File Name: </p>
                    <input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
                </div>
    

    这应该是:

        const currentFile = this.state;
        return(
            <div style={{border: "1px dashed black", padding: "4px"}}>
                <div>
                    <p> File Name: </p>
                    <input type="text" value={currentFile.fileName} name="fileName" onChange={this.handleChange} />
                </div>