LINUX.ORG.RU

Формы в React

 ,


0

1

Всем доброго времени суток, друзья! Являюсь бэкенд-разработчиком, но решил-таки освоить что-то из мира фронтенд-разработки помимо пресловутого jQuery. Выбрал React - и поначалу всё было гладко, пока не столкнулся с формами.

Мне нужно сделать форму для редактирования статей. То есть у меня есть компонента со списком названий статей и кнопками «редактировать» рядом с каждой. При нажатии на неё у меня должен выполняться аякс-запрос (получение самой статьи) и после этого должна открываться другая «страница» с формой, в которую подставлены значения из статьи (название, сам текст статьи и т.п.).

Вопрос заключается в том, что не понимаю, как правильно передать в компоненту «форма редактирования статьи» данные, которые вернул ajax. Через props - не катит, иначе будет readonly, через конструктор тоже, потому что объект компоненты «форма редактирования статьи» создаётся лишь один раз - при повторных нажатиях на «редактировать» буду видеть в форме значения предыдущей статьи. Как вообще это правильно делать? Очень не хочется юзать ref, потому что выглядит это как костыль какой-то.

Через props - не катит, иначе будет readonly

Что? Если хочешь пропсы — передаёшь с содержимым коллбэк вроде onChange, например.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Я спрашиваю именно про начальные значения. То есть у меня статья, допустим, называется «посиделки на linux.org». По идее, если я хочу её редактировать, то у меня в форме редактирования в input, соответствующем заголовку этой статьи, должно быть написано «посиделки на linux.org». Если я сделаю вот так: value={this.props.title}, то я не смогу менять содержимое этого input, разве нет?

dimuska139 ★★
() автор топика

В props передаёшь начальные значения, ими инициализируешь state в конструкторе. В render используешь state и вешаешь onchange, в котором обновляешь state.

А вообще если будешь часто работать с формами, советую заюзать одну из специализированных библиотек для этого дела. Руками каждый раз всё писать скучно.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

1) Это всё будет идеально работать до тех пор, пока я после редактирования одной статьи не захочу отредактировать следующую. Потому что компонента формы редактирования уже будет создана и так при редактировании первой статьи. Когда я попытаюсь редактировать вторую, конструктор вызван уже не будет, поэтому я в форме редактирования увижу данные предыдущей статьи.

2) Какую библиотеку порекомендуете?

dimuska139 ★★
() автор топика
Ответ на: комментарий от dimuska139

Если я сделаю вот так: value={this.props.title}, то я не смогу менять содержимое этого input, разве нет?

Конечно, сможешь, но только родителем, который этот props.title передаёт. Для родителя title может быть внутри стейта и он может управлять формой как угодно, в том числе и менять её, убирать, возвращать с любым другим текстом.

x3al ★★★★★
()

Грубо говоря,

const { currentArticle, isEditing } = this.state;
return (
  isEditing
    ? <FormComponent value=currentArticle onChange=(currentArticle) => this.setState({ currentArticle }) />
    : <div>
        <button onClick={() => this.setState({ isEditing: true })>Edit</button>
        <DisplayComponent>{currentArticle}</DisplayComponent> и дальше что угодно (другие статьи или что там)
     </div>
);

Добавить <Route> по вкусу (роутер спокойно заменит isEditing).

x3al ★★★★★
()
Ответ на: комментарий от dimuska139

1) Это всё будет идеально работать до тех пор, пока я после редактирования одной статьи не захочу отредактировать следующую. Потому что компонента формы редактирования уже будет создана и так при редактировании первой статьи. Когда я попытаюсь редактировать вторую, конструктор вызван уже не будет, поэтому я в форме редактирования увижу данные предыдущей статьи.

Ну тут сложно что-то говорить не видя, как ты компонент формы используешь и вообще как оно устроено. Если форма из дерева исчезает, то в следующий раз конструктор будет вызван, когда она там появится (т.е. при стандартном для веба использовании вида редактировать - новая форма - сохранить/отменить - форма исчезла). Если у тебя форма из дерева не исчезает, тогда можешь перегрузить метод componentWillReceiveProps() и там обновить state, например.

Legioner ★★★★★
()

Попробуй вместо React использовать Vue.

leprikon
()

Я использую componentDidMount для получения даных.

componentDidMount() {
    // ajax
}
jek04
()

из props перекинь в state, а после редактирования - отправляй на сервер ajax-ом

UPD. а вообще, здесь какой-нибудь flux подойдет

bvn13 ★★★★★
()
Последнее исправление: bvn13 (всего исправлений: 1)
8 марта 2019 г.

Ответ самому себе, спустя год

Всем привет! В общем, спустя год, освоил я-таки реакт в полной мере. В полной мере для того, чтобы достаточно спокойно на нем разрабатывать более-менее сложные интерфейсы. Ответ самому себе: пилить самостоятельно обработку форм - это костыли и велосипеды. Также не стоит данные полей формы по onChange гнать через redux - это сильно усложнит проект, да и вряд ли будет красивым решением.

Гораздо удобнее для этих целей (для работы с формами) взять готовую библиотеку типа react-final-form - и сэкономить таким образом уйму времени, сил, а код проекта сделать приятным и красивым. Там, например, есть свойство initialValues, позволяющее передать в форму значения прямо из пропсов, и все нормально будет изменяться, потому что эта логика (проброс из пропс в стейт) уже реализован внутри этой библиотеки. К слову, в github-репозитории react-final-form есть куча примеров на все случаи жизни.

То есть использование react-final-form или formik сразу решает кучу проблем, позволяя сосредоточиться на более важной логике проекта. Советую начинающим разработчикам в React использовать для обработки форма именно готовое решение, чтобы, столкнувшись с трудностями работы с формами, не потерять интерес к фронтент-разработке.

dimuska139 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.