Как присвоить значения состояниям после открытия формы редактирования?

Я пытаюсь создать свое первое простое внешнее приложение CRUD в React. У меня проблемы с формой редактирования.

Всякий раз, когда я отображаю форму редактирования с полями, заполненными значениями выбранной записи, мне нужно редактировать каждое поле, чтобы сохранить его обратно в базу данных. Если я не изменю ни одно из значений полей, включая идентификатор записи, или изменю только одно значение, я получаю сообщение об ошибке: [GraphQL error]: Message: could not convert string to float: , Location: undefined, Path: undefined. Я знаю, что могу добавить Mutation в Query, но тогда у меня возникают проблемы с повторной загрузкой обновленного списка записей в родительском компоненте, и я все еще получаю сообщение об ошибке, упомянутое выше.

export class EditForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            id: '',
            name: '',
            price: '',
            category: ''
        };
        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange = (event) => {
        const target = event.target;
        const value = target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    };

    updateSome = async () => {
      const {id, name, price, category} = this.state;
      await this.props.editOne({
          variables: {
              id,
              name,
              price,
              category
          },
          refetchQueries: [{ query: ones }]
      })
    };

    render() {
        return (
            <div>
                <Query query = {GET_ONE} variables = {{one: Number(this.props.id)}}>
        {({ loading, error, data, networkStatus }) => {
            if (loading) return "Loading...";
            if (error) return `Error! ${error.message}`;
            if (networkStatus === 4) return "Refetching!";
            return (
                <div>
                     {data.ones.map(one => (
                       <Form key = {one.id}>
                    <Row>
                        <Col>
                        <Form.Group>
                        <Form.Label>ID</Form.Label>
                            <Form.Control
                                name='id'
                                defaultValue = {one.id}
                                onChange = {this.handleInputChange}
                                type = "text"
                                placeholder = "id"
                            />
                        </Form.Group>
                        </Col>
                        <Col>
                        <Form.Group>
                        <Form.Label>Name</Form.Label>
                            <Form.Control
                                name='name'
                                defaultValue = {one.name}
                                onChange = {this.handleInputChange}
                                type = "text"
                                placeholder = "name"
                            />
                        </Form.Group>
                        </Col>
                        <Col>
                        <Form.Group>
                            <Form.Label>Price</Form.Label>
                            <Form.Control
                                name='price'
                                defaultValue = {one.price}
                                onChange = {this.handleInputChange}
                                type = "number"
                                step = {0.01}
                                placeholder = "price"
                            />
                        </Form.Group>
                        </Col>
                        <Col>
                        <Form.Group>
                            <Form.Label>Category</Form.Label>
                            <Query query = {twos}>
                                {({loading, error, data}) => {
                                    if (loading) return <Spinner animation = "border" role = "status">
                                                <span className = "sr-only">Loading...</span>
                                            </Spinner>;
                                    if (error) return `Error! ${error.message}`;
                                    return (
                                        <Form.Control name='category'
                                                      defaultValue = {one.category.id}
                                                      onChange = {this.handleInputChange}
                                                      as = "select"
                                                      placeholder = "category"
                                        >
                                            {data.twos.map(two => (
                                        <option key = {two.id} value = {two.id}>{two.category}</option>
                                                ))}
                                    </Form.Control>
                                    );
                                }}
                            </Query>
                        </Form.Group>
                        </Col>
                    </Row>
                    <ButtonToolbar>
                            <Button
                                variant = "primary"
                                onClick = {() => this.updateSome()}
                            >Update</Button>
                        </ButtonToolbar>
                </Form>
                    ))}
                </div>
            );
        }}
    </Query>
            </div>
        )
    }
}

Как присвоить начальные значения выбранной записи this.state.id, this.state.name и т. д. после отображения Component? Я знаю, как ввести некоторые значения в this.state в constructor вручную, но я хочу передать значения, отображаемые в полях формы, в this.state.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
192
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы, наверное, знаете, что использование setState вызывает повторную визуализацию и обновление в компоненте <Query/>. Компонент формы (с обработкой состояния и событий) должен быть помещен внутри <Query/>, чтобы избежать этого эффекта - getDerivedStateFromProps() для начального состояния.

В этом случае без рефакторинга достаточно условноsetState в render, например:

            <Query query = {GET_ONE} variables = {{one: Number(this.props.id)}}>
    {({ loading, error, data, networkStatus }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        if (networkStatus === 4) return "Refetching!";

        // one-time flag, it can be undefined/uninitialized
        if (!this.state.initialized) {
          this.setState( {
            initialized: true, // block this block
            id: data.someField,
            name: data.someField,
            price: data.someField,
            category: data.someField
          })
        }

        return (

Ошибка GraphQL, вероятно, относится к полю price, преобразовать типы в variables (внутри вызова this.props.editOne).

Я вполне понимаю вашу точку зрения, но я не уверен, как добраться до полей моей формы здесь. Простая ссылка не будет принята React, поэтому это должно быть что-то другое. Я пытался получить данные из Query, но что-то вроде data.ones.indexOf(0).id не дает мне идентификатор записи.

ZmuA 28.05.2019 15:24
data.ones[0].id ? console.info(data) ?
xadm 28.05.2019 15:53

Вы, конечно, знаете, что используете (сохраняете в состоянии) один набор переменных для множества записей... перезаписывая друг друга? Вероятно, вам нужен массив в состоянии для сохранения значений для всех записей.

xadm 28.05.2019 16:11

Другие вопросы по теме