Last active
May 17, 2025 13:24
-
-
Save sunmeat/1426f6782180966fc21621360156e9ac to your computer and use it in GitHub Desktop.
вариант взаимодействия с useContext
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, createContext, useContext } from 'react'; | |
import './css/FormContainer.css'; | |
// создание контекста для формы | |
const FormContext = createContext(null); | |
// контекст тут нужен для упрощения взаимодействия между родительской формой и её дочерними инпутами | |
// вместо передачи данных и функций через props на каждый уровень, createContext и useContext позволяют проще делиться | |
// состоянием (formData) и функцией обновления (handleChange) напрямую | |
// это будет особенно полезно, когда в форме будет много полей | |
// контекст применяется внутри FormInput, чтобы получать и изменять соответствующие значения без лишней связи с родителем | |
// дочерняя компонента, использует контекст для доступа к данным формы | |
function FormInput({ label, type, name }) { | |
// получение данных и функции обновления из контекста | |
const { formData, handleChange } = useContext(FormContext); | |
// обработчик изменений, вызывает коллбэк handleChange из контекста | |
const handleInputChange = (e) => { | |
handleChange(name, e.target.value); | |
}; | |
return ( | |
<div className="form-group"> | |
<label htmlFor={name}>{label}:</label> | |
<input | |
id={name} | |
type={type} | |
name={name} | |
value={formData[name]} | |
onChange={handleInputChange} | |
/> | |
</div> | |
); | |
} | |
// родительская компонента, управляет состоянием и предоставляет контекст | |
function FormContainer() { | |
// состояние формы | |
const [formData, setFormData] = useState({ | |
name: '', | |
email: '' | |
}); | |
// состояние для результата отправки | |
const [submitResult, setSubmitResult] = useState(null); | |
// коллбэк для обновления состояния формы | |
const handleChange = (field, value) => { | |
setFormData((prev) => ({ | |
...prev, | |
[field]: value | |
})); | |
}; | |
// коллбэк для обработки отправки формы | |
const handleSubmit = async (e) => { | |
e.preventDefault(); | |
// сброс результата перед отправкой | |
setSubmitResult(null); | |
try { | |
const response = await fetch('https://jsonplaceholder.typicode.com/users', { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify(formData) | |
}); | |
const data = await response.json(); | |
// логирование ответа API | |
console.log('ответ от API:', data); | |
setSubmitResult({ success: true, data }); | |
} catch (error) { | |
// обработка ошибок API | |
console.error('ошибка API:', error); | |
setSubmitResult({ success: false, error: error.message }); | |
} | |
}; | |
// явное использование провайдера | |
// React возвращает объект контекста, у которого есть два ключевых компонента: | |
// 1) FormContext.Provider — компонент-провайдер | |
// 2) FormContext.Consumer — компонент-потребитель (реже используется) | |
// компонент <FormContext.Provider> сам по себе — обычный React-компонент, созданный внутри createContext | |
// он принимает специальный проп value, который доступен всем вложенным компонентам, использующим useContext(FormContext) | |
return ( | |
<FormContext.Provider value={{ formData, handleChange }}> | |
<div className="form-container"> | |
<h2>регистрационная форма</h2> | |
<form onSubmit={handleSubmit}> | |
<FormInput | |
label="имя" | |
type="text" | |
name="name" | |
/> | |
<FormInput | |
label="e-mail" | |
type="email" | |
name="email" | |
/> | |
<button type="submit">отправить</button> | |
</form> | |
<div className="form-data"> | |
<h3>введённые данные:</h3> | |
<p>имя: {formData.name || '—'}</p> | |
<p>email: {formData.email || '—'}</p> | |
</div> | |
{submitResult && ( | |
<div className="result"> | |
{submitResult.success ? ( | |
<> | |
<p className="success">успешно отправлено!</p> | |
<pre>{JSON.stringify(submitResult.data, null, 2)}</pre> | |
</> | |
) : ( | |
<p className="error"> | |
ошибка: {submitResult.error || 'не удалось отправить'} | |
</p> | |
)} | |
</div> | |
)} | |
</div> | |
</FormContext.Provider> | |
); | |
} | |
export default FormContainer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment