如何在重新获取时更新所有组件 textarea/input 文本值(更新陈旧数据)?

How do I update all component textarea/input text values on refetch (updating stale data)?

以下子组件成功更新了每个渲染器的默认值并在更新时显示文本值。

但是...

当我导航到另一条记录时,我看不到更新后的文本框值发生了变化,它保留了前一条记录的值(甚至是该记录的更新状态)?

如何完全重新获取新值?

import React from 'react';
import './EditRisk.css';

export class EditRiskDetails extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            riskTitle: props.risk.risktitle,
            riskStatement: props.risk.riskstatement,
            riskContext: props.risk.riskcontext,
            clousreCriteria: props.risk.closurecriteria,
            onwerNotes: props.risk.ownernotes,
            approverComments: props.risk.approvercomments
        }
    }
    handleRiskTitleChange = (event) => {    
        this.setState({riskTitle: event.target.value});
        this.props.risk.risktitle = event.target.value; 
    }
    handleRiskStatementChange = (event) => {   
        this.setState({riskStatement: event.target.value}); 
        this.props.risk.riskstatement = event.target.value; 
    }
    handleRiskContextChange = (event) => {    
        this.setState({riskContext: event.target.value});
        this.props.risk.riskcontext = event.target.value;
    }
    handleClosureCriteriaChange = (event) => {    
        this.setState({closureCriteria: event.target.value}); 
        this.props.risk.closurecriteria = event.target.value;  
    }
    handleOwnerNotesChange = (event) => {    
        this.setState({ownerNotes: event.target.value});  
        this.props.risk.ownernotes = event.target.value; 

    }
    handleApproverCommentsChange = (event) => {    
        this.setState({approverComments: event.target.value});  
        this.props.data.approvercomments = event.target.value;
    }
    componentDidUpdate(e){
        
    }
    render() {
        return (
            <div id="details" class="tbl layout" border="1">
                <div class="tr text input">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Title
                    </div>
                    <div class="td input data text">
                        <input type="text" onKeyPress={this.handleRiskTitleChange} defaultValue={this.state.riskTitle}/>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Risk Statement
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={this.handleRiskStatementChange} defaultValue={this.state.riskStatement}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Context
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={this.handleRiskContextChange} defaultValue={this.state.riskContext}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Closure Criteria
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={this.handleClosureCriteriaChange} defaultValue={this.state.closureCriteria}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Owner Notes
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={this.handleOwnerNotesChange} defaultValue={this.state.ownerNotes}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Approver Comments
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={this.handleApproverCommentsChange} defaultValue={this.state.approverComments}></textarea>
                    </div>
                </div>
            </div>
        );
    }
}

一个相邻的子组件更新得很好:

import React from 'react';
import Select from 'react-select';
import { riskValue } from '../../common/Functions';
import './EditRisk.css';

export class EditRiskSummary extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedOwnerId: this.props.data.risk.ownerid,
            selectedApproverId: this.props.data.risk.approverid
        }
    }
    handleOwnerChange = (option) => {
        this.setState({selectedOwnerId: option.value});
        this.props.data.risk.ownerid = option.value;
    }
    handleApproverChange = (option) => {
        this.setState({selectedApproverId: option.value});
        this.props.data.risk.approverid = option.value;
    }
    componentDidUpdate(e) {
        let ownerChanged = this.state.selectedOwnerId !== e.data.risk.ownerid;
        let approverChanged = this.state.selectedApproverId !== e.data.risk.approverid;
        this.state = {
            selectedOwnerId: e.data.risk.ownerid,
            selectedApproverId: e.data.risk.approverid
        }
        return ownerChanged || approverChanged;
    }
    
    render() {
        return (
            <div className="tbl layout" id="summary">
                <div className="tr">
                    <div className="td label">Risk #</div>
                    <div className="td">{this.props.data.risk.riskid} [<a href="" onClick="ctrl.getRiskReport()">Risk Summary</a>]</div>
                    <div className="td label">
                        Current Risk
                    </div>
                    <div className="td {this.props.risk.currentlevel}">
                        {riskValue(this.props.data.risk.currentlevel, this.props.data.risk.currentlikelihood, this.props.data.risk.currentconsequence)}
                    </div>
                </div>   
                <div className="tr">
                    <div className="td label">        
                        Creator
                    </div>
                    <div className="td">
                        Admin
                    </div>
                    <div className="td label">
                        Risk State
                    </div>
                    <div className="td">
                        {this.props.data.risk.riskstate}
                    </div>
                </div>      
                <div className="tr">
                    <div className="td label">
                        Owner
                    </div>
                    <div className="td">
                        <Select value={this.props.data.users.filter(option => option.value === this.props.data.risk.ownerid)} 
                                options={this.props.data.users} 
                                onChange={this.handleOwnerChange.bind(this)} />
                    </div>
                    <div className="td label">
                        Risk Approver
                    </div>
                    <div className="td">
                        <Select value={this.props.data.users.filter(option => option.value === this.props.data.risk.approverid)} 
                                options={this.props.data.users} 
                                onChange={this.handleApproverChange.bind(this)} />
                    </div>
                </div>
            </div>
        );
    }
}

EditDetailRisks 组件存在以下错误。

  • this.props.risk.risktitle = event.target.value; 在 React 组件中,不建议直接更新 props 或 state。 您应该使用 setState 更新道具或状态。
  • 不更新更改值的原因是您将状态作为默认值传递,而不是文本区域中的值。 defaultValue 属性 用于仅在加载 DOM 元素时设置初始值。

我更新了 EditRiskDetails 组件代码,希望它能帮助您理解。

import React from 'react';
import './EditRisk.css';

export class EditRiskDetails extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            riskTitle: props.risk.risktitle,
            riskStatement: props.risk.riskstatement,
            riskContext: props.risk.riskcontext,
            clousreCriteria: props.risk.closurecriteria,
            onwerNotes: props.risk.ownernotes,
            approverComments: props.risk.approvercomments
        }
    }
    
    handleInputChange = (event, key) => {    
        this.setState({[key]: event.target.value});
    }

    componentDidUpdate(e){
        
    }
    
    render() {
        return (
            <div id="details" class="tbl layout" border="1">
                <div class="tr text input">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Title
                    </div>
                    <div class="td input data text">
                        <input type="text" onKeyPress={(event) => this.handleInputChange(event, "riskTitle")} value={this.state.riskTitle}/>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Risk Statement
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={(event) => this.handleInputChange(event, "riskStatement")} value={this.state.riskStatement}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Context
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={(event) => this.handleInputChange(event, "riskContext")} value={this.state.riskContext}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Closure Criteria
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={(event) => this.handleInputChange(event, "closureCriteria")} value={this.state.closureCriteria}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label"  style={{verticalAlign: 'top'}}>
                        Owner Notes
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={(event) => this.handleInputChange(event, "ownerNotes")} value={this.state.ownerNotes}></textarea>
                    </div>
                </div>
                <div class="tr">
                    <div class="td label" style={{verticalAlign: 'top'}}>
                        Approver Comments
                    </div>
                    <div class="td data"  style={{verticalAlign: 'top'}}>
                        <textarea onKeyPress={(event) => this.handleInputChange(event, "approverComments")} value={this.state.approverComments}></textarea>
                    </div>
                </div>
            </div>
        );
    }
}