首页 > 解决方案 > 执行 Axios 获取请求后如何设置输入的值?

问题描述

我有一个组件,它代表用于输入书籍数据的表单,例如标题/作者/等。

如果存在 ID,则组件将对 API 服务器进行 API 调用,并获取图书数据。

我想要完成的基本上是从 API 服务器获取记录,然后将表单字段设置为这些值,以便表单填充数据供用户编辑。

我有一个调用loadBookAPI 的方法来获取图书数据。该方法有效,它获取记录,设置状态,但表单输入似乎没有发现状态已更改。

我需要做什么才能让表单填充刚刚获取的记录?

import React from "react";
import Axios from "axios";
import {
    Redirect
} from "react-router-dom";

import FormBase from "../FormBase";

export default class BookForm extends FormBase {
    constructor(props) {
        super(props);
        this.state = {
            formFields: {
                title: '',
                author_id: null,
                cover_image: null
            },
            authors: [],
        };
    }

    componentDidMount() {
        this.loadAuthors();
        if (this.props.id) {
            this.loadBook()
        }
    }

    loadBook = () => {
        Axios.get(`${process.env.REACT_APP_API_URL}/books/${this.props.id}`).then(response => {
            this.setState(prevState => {
                let formFields = Object.assign({}, prevState.formFields)
                formFields['title'] = response.data['title']
                formFields['author_id'] = response.data['author_id']
                return {formFields}
            })
        })
    }

    loadAuthors = () => {
        Axios.get(`${process.env.REACT_APP_API_URL}/authors`).then(response => {
            this.setState({authors: response.data})
        })
    }

    render() {
        let authors = this.state.authors.map(author => {
            return <option key={author.id} value={author.id}>{author.last_name}, {author.first_name}</option>
        })
        return (
            <form onSubmit={(e) => {e.preventDefault(); this.props.handleSubmit(e, this.state.formFields, true)}}>
                {this.state.redirect ? <Redirect to="/admin/books" /> : null}
                <div className="form-group">
                    <label htmlFor="title">Title</label>
                    <input name="title" value={this.state.title} onChange={this.handleFieldChange} type="text" className="form-control" />
                </div>
                <div className="form-group">
                    <label htmlFor="author">Author</label>
                    <select name="author_id" onChange={this.handleFieldChange} className="custom-select" size="5">
                        {authors}
                    </select>
                </div>
                <div className="custom-file form-group">
                    <input name="cover_image" type="file" onChange={this.handleFieldChange} className="custom-file-input" id="customFile" />
                    <label className="custom-file-label" htmlFor="customFile">Cover Image</label>
                </div>
                <button style={{marginTop: '1rem'}} type="submit" className="btn btn-primary">Submit</button>
            </form>
        )
    }
}

标签: reactjs

解决方案


我基本上遵循了这个关于不受控制的组件的指南。

我使用 为每个表单字段添加属性React.createRef(),然后在表单输入上链接 ref 对象,如ref={this.author_id}. 然后,您可以这样做this.author_id.current.value = response.data.author_id,然后将设置输入的值。但这不会触发onChange,因此您也需要更新状态。

import React from "react";
import Axios from "axios";
import {
    Redirect
} from "react-router-dom";

import FormBase from "../FormBase";

export default class BookForm extends FormBase {
    constructor(props) {
        super(props);
        this.state = {
            formFields: {
                title: '',
                author_id: null,
                cover_image: null
            },
            authors: [],
        };
        this.title = React.createRef();
        this.author_id = React.createRef();
    }

    componentDidMount() {
        this.loadAuthors();
        if (this.props.id) {
            this.loadBook()
        }
    }

    loadBook = () => {
        Axios.get(`${process.env.REACT_APP_API_URL}/books/${this.props.id}`).then(response => {
            console.log(this.author_id)
            this.author_id.current.value = response.data.author_id
            this.title.current.value = response.data.title
            this.setState(prevState => {
                let formFields = Object.assign({}, prevState.formFields)
                formFields['title'] = response.data['title']
                formFields['author_id'] = response.data['author_id']
                return {formFields}
            })
        })
    }

    loadAuthors = () => {
        Axios.get(`${process.env.REACT_APP_API_URL}/authors`).then(response => {
            this.setState({authors: response.data})
        })
    }

    render() {
        let authors = this.state.authors.map(author => {
            return <option key={author.id} value={author.id}>{author.last_name}, {author.first_name}</option>
        })
        return (
            <form onSubmit={(e) => {e.preventDefault(); this.props.handleSubmit(e, this.state.formFields, true)}}>
                {this.state.redirect ? <Redirect to="/admin/books" /> : null}
                <div className="form-group">
                    <label htmlFor="title">Title</label>
                    <input name="title" ref={this.title} value={this.state.title} onChange={this.handleFieldChange} type="text" className="form-control" />
                </div>
                <div className="form-group">
                    <label htmlFor="author">Author</label>
                    <select name="author_id" ref={this.author_id} onChange={this.handleFieldChange} className="custom-select" size="5">
                        {authors}
                    </select>
                </div>
                <div className="custom-file form-group">
                    <input name="cover_image" type="file" onChange={this.handleFieldChange} className="custom-file-input" id="customFile" />

推荐阅读