ReactJS警告组件将不受控制的隐藏字段更改为受控

时间:2019-01-11 13:06:43

标签: reactjs

我有一个隐藏字段,其中包含一个csrf令牌,该令牌的值在node-fetch成功返回JSON对象后设置,因此我不确定为什么会根据当前设置收到以下警告。据我所知,如果使用受控或非受控方法来更新和设置输入字段,则应该引发此警告,但是我觉得仅将prop设置为值不符合我在文档中阅读的标准。

Warning: A component is changing an uncontrolled input of type hidden to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

位于:

in input (created by ActivityFeedSearchForm)
    in form (created by ActivityFeedSearchForm)
    in div (created by ActivityFeedSearchForm)
    in div (created by ActivityFeedSearchForm)
    in div (created by ActivityFeedSearchForm)
    in ActivityFeedSearchForm (created by ActivityFeed)
    in div (created by ActivityFeed)
    in ActivityFeed

现在这是我从父母到孩子的代码,其中会发出警告:

ActivityFeed:

export default class ActivityFeed extends React.Component{

    export default class ActivityFeed extends React.Component{
    constructor(props, context) {
        super(props, context);
        this.state = this.context.data || window.__INITIAL_STATE__ || { test: [] };
    }

    fetchList() {
        fetch(`${API_ROOT}` + '/api' + window.location.search, { compress: false })
            .then(res => {
                return res.json();
            })  
            .then(data => {
                this.setState({ 
                    ...
                    csrf: data.csrfToken, 
                    ...
                });
            });
    }

    componentDidMount() {
        this.fetchList();
    }

    render() {  
            return (
                <div>
                    <Navigation notifications={this.state.notifications}/>
                    <ActivityFeedSearchForm csrf={this.state.csrf} ... />
                </div>
            )
        }
    }
}

ActivityFeedSearchForm:

//Activity Feed - Search Form
export default class ActivityFeedSearchForm extends React.Component {
        render() {
        var clearFilters;
        if(this.typeQuery || this.props.categoryQuery || this.props.departmentQuery || this.props.teamQuery || this.props.startDateQuery || this.props.endDateQuery || this.props.typeQuery){
            clearFilters = <a href="/app" id="clear-filter">Clear</a>;
        }

        return (
            <div className="row">
                <div className="feed-search-form col-md-10 col-md-offset-1">
                    <div clas="row">
                        <form action="/app" method="post" className="feed-filter-fields">
                            <input type="hidden" name="_csrf" value={this.props.csrf}/>
                            ...
                            <div className="col-md-1 feed-filter-section filter-button-container">
                                <button type="submit" id="feed-filter-submit">Filter</button>
                                {clearFilters}
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        )
    }
}

3 个答案:

答案 0 :(得分:0)

您已经发现问题所在,是定义<input type="hidden" name="_csrf" value={this.props.csrf}/>的地方。

您的csrf可能首先是未定义(输入不受控制),然后通过设置一个值将其更改为受控输入。

如果要使其不受控制,只需使用defaultProps设置默认props值:

ActivityFeedSearchForm.defaultProps = {
  csrf: null,
}

答案 1 :(得分:0)

我同意先前的回答,我请您参考官方文档:https://reactjs.org/docs/uncontrolled-components.html 您需要检查是否有谁将输入值初始化的异步事件。如果生命周期中的某个时间值未定义,则会显示错误消息A component is changing an uncontrolled input etc...

答案 2 :(得分:0)

首先,决定是否要对该表单元素进行控制(通过React状态和/或JS逻辑以编程方式设置的值)或不受控制(由用户设置的值)输入)。

如果您想要受控输入

很有可能,因为它是隐藏的输入!看起来您希望此输入受到控制,但是,当React看到undefined传递给其value道具时,这使React认为您希望它不受控制。 / p>

要解决此问题,当您想告诉React该输入的值是虚假的值而不是''时,请传递一个空字符串0undefined(这将导致此警告)或null(这将引起另一个警告)。理想情况下,您应该更改应用程序逻辑,以确保将''0始终设置为空状态。

或者...快速的肮脏解决方案是这样的:

<input value={yourValue || ''} />

如果您想要不受控制的输入

(不太可能是隐藏的输入...)

不要设置value道具。相反,请设置defaultValue道具。

如果您想要一个伪控制输入,当某些值变量发生更改时,输入中显示的内容也会更改,而且用户也可以对其进行编辑,则可以尝试类似的操作,其中元素的键在传递时会更改-在价值上,让React像对待新的替换元素一样对待:

<input defaultValue={yourValue} key={`some-key-${yourValue}`} />

...但是,这也会导致输入值在defaultValue更改时失去焦点。