首页 > 解决方案 > 如何在 React 中强制重新渲染表单中的输入字段?

问题描述

我正在尝试创建一个表单,用户可以在其中编辑数据库中的联系人信息,然后保存这些更改。表单正确加载并保存了数据库中的信息,但是当 componentDidMount() 将当前信息加载到表单字段中时,字段不会重新呈现,从而导致模板文本(即姓名、电子邮件等)和从数据库加载的信息相互叠加显示。单击任何输入字段会导致单击的字段正确呈现,文本显示在输入字段上方,而不是加载的文本上方。

在componentDidMount()中正确加载数据后,如何强制表单重新呈现每个字段?我试过 forceUpdate() 但它没有用,而且我找不到其他人遇到这个问题。我怀疑这与我使用错误的引导样式有关,但即使在阅读了引导的所有文档之后,我也找不到与我的问题相关的任何内容。

这里有几个屏幕截图来显示这个问题。

加载后的表单

加载后的表单

单击“名称”字段后的表单

单击“名称”字段后的表单

这是组件的相关代码。

    constructor(props) {
        super(props);

        this.state = {
            name: "",
            email: "",
            role: "",
            phone: "",
            errors: {}
        }
    }

    // Initializer: Copy contact's current data to state
    componentDidMount() {
        axios.get("/api/contacts/get/" + this.props.match.params.id)
            .then(res => {
                this.setState({ name: res.data.name });
                this.setState({ email: res.data.email });
                this.setState({ role: res.data.role });
                this.setState({ phone: res.data.phone });
            })
            .catch(err => console.log(err));

        this.forceUpdate();
    }

    // Change handler: Modify values when changed
    onChange = e => {
        this.setState({ [e.target.id]: e.target.value });
    }

    // Submit handler: Save changes to database
    onSubmit = e => {
        e.preventDefault();

        const contact = {
            name: this.state.name,
            email: this.state.email,
            role: this.state.role,
            phone: stripNumber(this.state.phone)
        };

        // Post modified contact to database, then navigate back to Manage Contacts Dashboard
        axios.post("/api/admin/contacts/update/" + this.props.match.params.id, contact);
        window.location = PREVIOUS_URL;
    }

    render() {
        const { errors } = this.state;

        return (
            <div>
                <Link to={PREVIOUS_URL} className="btn-flat waves-effect">
                    <i className="material-icons left">keyboard_backspace</i> Back to Manage Contacts
                </Link>
                <h3>Edit contact</h3>
                <form noValidate onSubmit={this.onSubmit}>
                    <div className="input-field col s12">
                        <input
                            onChange={this.onChange}
                            value={this.state.name}
                            error={errors.name}
                            id="name"
                            type="text"
                            className={classnames("", { invalid: errors.name })}
                        />
                        <label htmlFor="name">Name</label>
                        <span className="red-text">{errors.name}</span>
                    </div>
                    <div className="input-field col s12">
                        <input
                            onChange={this.onChange}
                            value={this.state.email}
                            error={errors.email}
                            id="email"
                            type="email"
                            className={classnames("", { invalid: errors.email || errors.emailnotfound })}
                        />
                        <label htmlFor="email">Email</label>
                        <span className="red-text">{errors.email}{errors.emailnotfound}</span>
                    </div>
                    <div className="input-field col s12">
                        <input
                            onChange={this.onChange}
                            value={this.state.role}
                            error={errors.role}
                            id="role"
                            type="text"
                            className={classnames("", { invalid: errors.role })}
                        />
                        <label htmlFor="role">Role</label>
                        <span className="red-text">{errors.role}</span>
                    </div>
                    <div className="input-field col s12">
                        <input
                            onChange={this.onChange}
                            value={this.state.phone}
                            error={errors.phone}
                            id="phone"
                            type="tel"
                            className={classnames("", { invalid: errors.phone })}
                        />
                        <label htmlFor="phone">Phone Number</label>
                        <span className="red-text">{errors.phone}</span>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Submit changes" className="btn btn-primary" />
                        <Link to={PREVIOUS_URL} className="btn btn-danger">  Cancel  </Link>
                    </div>
                </form>
            </div>
        )
    }
}

标签: javascriptnode.jsreactjstwitter-bootstrap

解决方案


您是否尝试过在内部进行数据提取componentWillMount()


推荐阅读