Обновление вложенных данных в функциональном компоненте - PullRequest
0 голосов
/ 19 июня 2020

У меня есть следующие данные:

    const INITIAL_DATA = [
    {
        "id": 1,
        "name": "Name 1",
    },
    {
        "id": 2,
        "name": "Name 2",
    }
];  

Я устанавливаю INITIAL_DATA с помощью useState, а также объявляю новую переменную состояния с первым элементом массива данных.

const [data, setData] = useState(INITIAL_DATA);
const [single, setSingle] = useState(data[0]);  

После выбора отдельных данных из списка:

{data.map(function (d, idx) {
  return (
   <li key={idx} onClick={() => handleOnClick(idx)}>
     {d.name}
   </li>
 )
})}  

со следующим обработчиком:

const handleOnClick = (id) => {
  setSingle(data[id]);
}  

переменная состояния single также заполняет форму «имя» (single.name).
Теперь я пытаюсь обновить форму или поле ввода «имя», а также обновить набор данных с новым значением, но я застрял.

    const handleInputChange = e => {
    //const { name, value } = e.target
    //setValues({...values, [name]: value})
}  

Это мой обработчик изменения ввода. Мне удается прочитать значение, но я застрял в том, как соответствующим образом обновить вложенный массив. Мне нужно отредактировать массив и обновить переменную состояния данных новым и обновленным массивом.

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Прежде всего, нужно было контролировать ввод, поэтому, добавив текстовое состояние, вы можете обновить его, используя handleInputChange и setText.

Затем onSubmit ничего не получал, поскольку ввод был not register, поэтому ref={register} добавляется к вводу для получения данных формы.

Далее я черпал вдохновение из комментария об использовании идентификатора в состоянии для обновления массива данных при отправке формы.

Это обновленный файл. Извините, мой линтер мог немного изменить некоторые интервалы

import React, { useState } from 'react';
import { useForm } from "react-hook-form";

import CollapseSection from '../components/UI/Collapse/CollapseSection'

import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';

const Verbraucher = () => {
    const INITIAL_DATA = [
        {
            "id": 1,
            "name": "Test 1",
        },
        {
            "id": 2,
            "name": "Test 2",
        }
    ];
    const [data, setData] = useState(INITIAL_DATA);
    const [id, setId] = useState(0);
    const [text, setText] = useState(data[id].name);

    // For react forms
    const { register, handleSubmit } = useForm();
    const onSubmit = (single) => {
      const d = [...data];
      d[id] = { ...single, name: single.name };
      setData(d);
    };

    const handleOnClick = (idx) => {
      setId(idx);
      setText(data[idx].name);
    }

    const handleInputChange = e => {
      const { value } = e.target;
      setText(value);
    }

    return (
        <CollapseSection
            title="Test"
            appear={true}
        >
            <Container className="sectionVerbraucher p-0 mb-3">
                <Row className="no-gutters">
                    <Col className="col" xs={12} md={6}>
                        <Row className="bg-white m-0">
                            <Col className="p-3" xs={12} md={12}>
                                <form onSubmit={handleSubmit(onSubmit)}>
                                    <h1>Test</h1>
                                    <hr />
                                    <input
                                        ref={register}
                                        name="name"
                                        value={text}
                                        onChange={handleInputChange}
                                    />
                                    <input type="submit" />
                                </form>
                            </Col>
                        </Row>
                    </Col>

                    <Col className="col colSummary bg-white p-3" xs={12} md={6}>
                        <ul className="listAll">
                            {data.map(function (d, idx) {
                                return (
                                    <li key={idx} onClick={() => handleOnClick(idx)}>
                                        {d.name}
                                    </li>
                                )
                            })}
                        </ul>
                    </Col>
                </Row>
            </Container>
        </CollapseSection>
    )
}

export default Data;
0 голосов
/ 19 июня 2020

Я думаю, что ваше состояние может быть идентифицировано вашим источником данных и текущим выбранным элементом, вы можете изменить свой код следующим образом:

const [data, setData] = useState(INITIAL_DATA);
// The id of the currently selected item
const [id, setId] = useState(0);

// At every render pick the currently selected data
const single = data[id];

const handleOnClick = (id) => {
  // onClick change the selected id forcing a re-render 
  setId(id);
}  

const handleInputChange = e => {
  const { name, value } = e.target;
  // When the input changes, update the data
  // and force a re-render
  setData((data) => {...data, [name]: value})
}  
...