React 将受控错误变为不受控制的错误让我发疯,我做错了啥?

Posted

技术标签:

【中文标题】React 将受控错误变为不受控制的错误让我发疯,我做错了啥?【英文标题】:React's changing controlled to uncontrolled error driving me crazy, what am I doing wrong?React 将受控错误变为不受控制的错误让我发疯,我做错了什么? 【发布时间】:2019-05-08 00:06:06 【问题描述】:

我已在此处询问有关该错误的更多信息:Should I ignore React warning: Input elements should not switch from uncontrolled to controlled?。但我还是卡住了..

所以我有一个案例,我想将时间输入字段从保留它自己的值切换到从另一个时间输入字段中接管一个值。我正在使用一个简单的“锁定”/“解锁”按钮来执行此操作。单击该按钮允许我选择输入字段是锁定(从其他人那里接管值)还是解锁(保留自己的值)。 我在循环中执行此操作,因为每个时间字段将重复 7 次(每天)。

问题

但是,每次我从常规时间输入字段切换到后面有操作的时间输入字段时,React 都会给我以下错误:组件正在更改时间类型的不受控制的输入被控制。输入元素不应从不受控切换到受控(反之亦然)。在组件的生命周期内决定使用受控输入元素还是不受控输入元素

解释下面的代码

cmets 之间的部分如下:如果当前日期输入字段的锁定状态为“true”,则输入必须从状态中获取值并执行 onchange 处理程序。如果它是假的,它不应该做任何事情并作为一个基本的输入字段做出反应。

我有什么

export class OpeningHoursTable extends Component
    constructor(props) 
        super(props);
        this.state = 
            sharedInputMo : '',
            empty: undefined
        ;
    
    render() 
        const Days = [id: 1, day: 'Monday',id: 2, day: 'Tuesday',id: 3, day: 'Wednesday',id: 4, day: 'Thursday',id: 5, day: 'Friday',id: 6, day: 'Saturday',id: 7, day: 'Sunday'];
        const Table = Days.map((id, day) => (
            <div key=id className='ohTableRow'>
                <div className='ohTableMorning'>
                    <div className='ohTableContentBlock'>day</div>
                    <div className='ohTableContentBlock'>
// THIS IS THE PART THAT GIVES ME THE ERROR
                         <input type='time' 
                                value=this.state['lock' + day + '_mo'] === true ? this.state.sharedInputMo || this.state.empty: this.state.empty 
                                onChange=this.state['lock' + day + '_mo'] === true ? thisInput => this.setState(sharedInputMo : thisInput.target.value ) : null  
                         />
// THIS IS THE PART THAT GIVES ME THE ERROR
                     </div>

                    <div className='ohTableLockState' onClick=this.state['lock' + day + '_mo'] === true ? () => this.setState( ['lock' + day + '_mo'] : false ) : () => this.setState( ['lock' + day + '_mo'] : true ) >
                        this.state['lock' + day + '_mo'] === true ?
                            <Icon name='Locked' />
                        :
                            <Icon name='Unlocked' />
                        
                    </div>

                </div>
            </div>
        ));
        return (
            <div className='ohTable'>
                Table
            </div>
        );
    

【问题讨论】:

【参考方案1】:

问题的根源和错误在于您提供了undefined 作为输入值,并且最初没有分配任何onChange 事件。

更具体地说,您将this.state.empty 作为一个值传递,该值在状态中被分配一个undefinednull 作为onChange 处理程序。

当 react 获取 undefined 作为输入值且没有处理程序时,它假定此输入不受控制,所有更改都将由 DOM 处理,并且 react 本身不应对其进行任何操作。

但是,稍后,根据用户操作,您的输入会获得另一个值 this.state.sharedInputMoonChange 处理程序,将其转换为受控输入。这种变化会导致 react 的混乱并给你这个警告。

【讨论】:

但这实际上是我需要的.. 可以通过单击按钮从不受控制切换到受控制的输入。 (所以,输入从用户那里获取价值,或者输入从状态中获取价值)那我该怎么做呢?【参考方案2】:

所以在休息了一晚后,我解决了自己的问题。 这适用于需要在受控对象和不受控对象之间切换并且具有相同错误的每个人。 使用 Switch 语句在受控对象和不受控对象之间切换。这样,React 会将它们视为一个单独的不同对象;因此在前端看起来好像你有相同的对象。

switch(this.state['lock' + day + '_mo']) 
                case true:
                    return (
                        <div className='ohTableContentBlock'>
                            <input type='time' value=this.state.sharedInputMo onChange=inputValue => this.setState(sharedInputMo2 : inputValue.target.value ) />
                        </div>
                    );
                case false:
                    return (
                        <div className='ohTableContentBlock'>
                            <input type='time' />
                        </div>
                    );
                default:
                    return (
                        <div className='ohTableContentBlock'>
                            <input type='time' />
                        </div>
                    );
            

【讨论】:

以上是关于React 将受控错误变为不受控制的错误让我发疯,我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

电子邮件输入警告 - 组件正在将文本类型的受控输入更改为不受控制

反应表单错误将类型文本的受控输入更改为不受控制

不受控制的输入 React Hooks

警告:组件正在将文本类型的受控输入更改为不受控制。 (反应.js)

组件正在将不受控制的自动完成更改为受控

受控组件与不受控制的组件有什么区别?