#javascript #reactjs
#javascript #reactjs
Вопрос:
Итак, я работаю над модальной формой для изменения объекта (т. Е. Продавца). Я могу либо отправить пустой объект в свой реквизит, чтобы добавить продавца, либо передать существующий объект продавца для их редактирования.
Я могу привязать значения к своим элементам управления, но я не уверен, как заставить 2-стороннюю привязку работать с любыми изменениями значения. Я предполагаю, что это будет какой-то onChange
синтаксис, возможно, с локальным useState
объектом для хранения изменений, но не уверен, как это будет выглядеть.
Рад предоставить более подробную информацию или контекст, если это необходимо.
import React from 'react';
import Modal from '../components/Modal'
function ModifySalespersons(props) {
function submit(salesperson) {
console.log(salesperson);
// return new salesperson object
props.setIsOpen(false);
}
return (
<Modal isOpen={props.isOpen} setIsOpen={props.setIsOpen} content={
<>
<div>
<div>
<h3 class="text-lg leading-6 font-medium text-gray-900">
Salesperson Information
</h3>
</div>
<form class="mt-6 sm:mt-5">
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label for="first_name" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
First name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input value={props.salesperson.firstName} id="first_name" class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
</div>
</div>
<div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start">
<label for="last_name" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
Last name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input value={props.salesperson.lastName} id="last_name" class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
</div>
</div>
<div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label for="address1" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
Address
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input value={props.salesperson.address1} id="address1" class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
</div>
</div>
{/* more controls here */}
</form>
</div>
<div class="mt-5 sm:mt-6 space-y-2">
<span class="flex w-full rounded-md shadow-sm">
<button onClick={() => submit(props.salesperson)} type="button" class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-indigo-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo transition ease-in-out duration-150 sm:text-sm sm:leading-5">
Submit
</button>
</span>
<span class="flex w-full rounded-md shadow-sm">
<button onClick={() => props.setIsOpen(false)} type="button" class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-white text-base leading-6 font-medium text-gray-500 shadow-sm hover:bg-gray-100 focus:outline-none focus:border-gray-700 focus:shadow-outline-gray transition ease-in-out duration-150 sm:text-sm sm:leading-5">
Cancel
</button>
</span>
</div>
</>
} />
);
}
export default ModifySalespersons;
Комментарии:
1. Вы можете использовать
const [salesperson, setSalesperson] = useState(props.salesperson || {})
и в JSXsalesperson..
вместоprops.salesperson..
и, как вы сказали, добавитьonChange
слушателей к входным данным и изменить состояние.
Ответ №1:
ШАГИ
- Инициализируйте свое состояние с помощью реквизита из родительского элемента, который переносится
Salesperson
. - Свяжите свое состояние с полями ввода, используя
value
from state иonChange
. - Передайте вашей функции
Salesperson
, которая принимает вашего нового отредактированного продавца. - После отправки формы вызовите свою функцию, переданную от дочернего элемента, и выполните следующий шаг.
Вы можете проверить рабочий пример здесь -> https://stackblitz.com/edit/react-jghg5q
import React from "react";
import Modal from "../components/Modal";
export default function ComponentThatWrapsModifySalespersons() {
function handleSubmit(newSalesperson) {
console.log(newSalesperson);
}
return (
<ModifySalespersons
salesperson={{ firstName: "hello", lastName: "world", address: "calif" }}
onSubmit={handleSubmit}
/>
);
}
function ModifySalespersons(props) {
const [state, setState] = React.useState({ ...props.salesperson });
function handleChange(e) {
const key = e.target.name;
const value = e.target.value;
setState(prev => ({
...prev,
[key]: value
}));
}
function submit() {
// return new salesperson object
props.onSubmit(state);
// props.setIsOpen(false);
}
console.log(state);
return (
<>
<div>
<div>
<h3 class="text-lg leading-6 font-medium text-gray-900">
Salesperson Information
</h3>
</div>
<form class="mt-6 sm:mt-5">
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
for="first_name"
class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2"
>
First name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input
name="firstName"
onChange={handleChange}
value={state.firstName}
id="first_name"
class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5"
/>
</div>
</div>
</div>
<div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start">
<label
for="last_name"
class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2"
>
Last name
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input
name="lastName"
onChange={handleChange}
value={state.lastName}
id="last_name"
class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5"
/>
</div>
</div>
</div>
<div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
for="address1"
class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2"
>
Address
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg rounded-md shadow-sm sm:max-w-xs">
<input
name="address"
onChange={handleChange}
value={state.address}
id="address1"
class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5"
/>
</div>
</div>
</div>
{/* more controls here */}
</form>
</div>
<div class="mt-5 sm:mt-6 space-y-2">
<span class="flex w-full rounded-md shadow-sm">
<button
onClick={submit}
type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-indigo-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo transition ease-in-out duration-150 sm:text-sm sm:leading-5"
>
Submit
</button>
</span>
<span class="flex w-full rounded-md shadow-sm">
<button
onClick={() => props.setIsOpen(false)}
type="button"
class="inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-white text-base leading-6 font-medium text-gray-500 shadow-sm hover:bg-gray-100 focus:outline-none focus:border-gray-700 focus:shadow-outline-gray transition ease-in-out duration-150 sm:text-sm sm:leading-5"
>
Cancel
</button>
</span>
</div>
</>
);
}
Комментарии:
1. Спасибо! Вот-вот закончится, и я смотрю на это на мобильном устройстве, но, кажется, я понимаю, к чему вы клоните. Сегодня вечером я снова посмотрю на это.
2. Хорошо, круто. Кажется, я понял. Мне потребовалась минута, но мне не хватало
name
атрибута, который позволил бы мне обновить поле. Оцените это!
Ответ №2:
для этой цели вы можете использовать useEffect . он будет искать изменения в вашем props.salesperson и действовать соответствующим образом
const [isForEdit , setIsForEdit] = useState(false);
useEffect( () => {
setIsForEdit(). /// -> true or false based on the value of props.salesperson
}, [props.salesperson])
теперь, основываясь на значении isForEdit, вы можете решить делать все, что захотите.