предисловие
Ты с нетерпением ждешь мира, надеюсь, у тебя нетbug
. Всем привет! Я Лин Дуан.
У меня в последнее время мало что выводится😂, то ли стоп-уведомление, то ли"软文"
, все еще немного смущен. Это не большая проблема, я сказал (пи) Цянь (толстый) слегка 😄.
Итак, сегодня поговорим о вещах, связанных с технологиями, которым посвящена эта статья, — управляемых и неуправляемых компонентах.
Причина написания этой статьи - продолжать писатьHOC
Иногда это включает в себя содержание контролируемых и неконтролируемых компонентов, и тогда я обнаружил, что есть еще много содержания, чтобы сказать, но после поиска учебников в Интернете большинство учебных материалов запутаны, и это нелегко для новичков. чтобы понять.
Поэтому я также надеюсь, что смогу полностью раскрыть свои сильные стороны и сделать эту часть содержания короткой и лаконичной, чтобы все могли ее понять.
(Да, длинное здесь — это то, что вы считаете длинным, а короткое — это не то, что вы считаете коротким...)
Ладно👌, без скина😁, давайте посмотрим, чему вы можете научиться, прочитав эту статью:
- Основные понятия управляемых компонентов
- выбрать контролируемый компонент
- Динамический корпус компонента с контролируемой формой
- неконтролируемые компоненты
- Специальная файловая метка
текст
Основные понятия управляемых компонентов
Из названий мы можем догадаться, что означают эти два слова:
- Контролируемые компоненты: Компоненты под нашим контролем
- Неконтролируемые компоненты: Компоненты, которые не находятся под нашим контролем.
(Разве это не вздор Тимо...)
Агем, хорошо, что вы имеете в виду под контролируемым и неконтролируемым здесь? На самом деле, мыКонтроль над состоянием компонента, может ли его значение быть установлено только пользователем, не контролируется кодом.
мы знаем, что вReact
определяетinput
поле ввода, в нем нет чего-то вродеVue
внутриv-model
Это двусторонняя привязка. Другими словами, у нас нет поля ввода команды и данных, которое может объединять пользовательский ввод в поле ввода, а затем обновлять синхронизацию данных.
Как этот случай:
class TestComponent extends React.Component {
render () {
return <input name="username" />
}
}
Когда пользователь вводит контент в поле ввода на интерфейсе, он поддерживает"state"
, чтобы он мог сделать это сам на основе ввода пользователяUI
обновление на . (этоstate
не то, что мы обычно видимthis.state
, но абстрагируется от каждого элемента формыstate
)
Подумайте, что мы можем сделать, если хотим контролировать содержимое поля ввода в это время? Ну... содержимое поля ввода зависит отinput
серединаvalue
имущество, то мы можемthis.state
определить именованныйusername
свойства и воляinput
Вверхvalue
Указано как это свойство:
class TestComponent extends React.Component {
constructor (props) {
super(props);
this.state = { username: 'lindaidai' };
}
render () {
return <input name="username" value={this.state.username} />
}
}
Но тогда вы найдетеinput
Содержание - только чтение, потому чтоvalue
будет нашимthis.state.username
контролируется, когда пользователь вводит новый контент,this.state.username
не обновляется автоматически, поэтомуinput
Содержимое внутри не изменится.
ха-ха, как вы уже поняли, мы можем использоватьonChange
события для прослушивания изменений во входном содержимом и использованияsetState
возобновитьthis.state.username
:
class TestComponent extends React.Component {
constructor (props) {
super(props);
this.state = {
username: "lindaidai"
}
}
onChange (e) {
console.log(e.target.value);
this.setState({
username: e.target.value
})
}
render () {
return <input name="username" value={this.state.username} onChange={(e) => this.onChange(e)} />
}
}
Теперь независимо от того, что пользователь вводитstate
а такжеUI
будет обновлен, и мы сможем использовать его в другом месте компонента.this.state.username
получитьinput
контент также может быть доступен черезthis.setState()
Модифицироватьinput
содержание в.
Хорошо 👌, а теперь посмотримУправляемые компонентыОпределение:
В элементах формы HTML они обычно поддерживают наборstate
, и сделать это самостоятельно с пользовательским вводомUI
上的更新,这种行为是不被我们程序所管控的。 И еслиReact
внутреннийstate
Атрибуты и значения элементов формы устанавливают зависимости, а затем передаютonChange
событие иsetState()
комбинированное обновлениеstate
Атрибуты, вы можете управлять работой формы в процессе пользовательского ввода. одеялоReact
Элементы ввода формы, управляющие значением таким образом, называютсяУправляемые компоненты.
(Ну, я думаю, приведенное выше резюме 👆 можно использовать в интервью)
выбрать контролируемый компонент
оставайся на вершинеinput
Я продемонстрировал всем самый простой управляемый компонент, по сути, он похож на другие элементы формы, которые могут быть просто другими именами атрибутов и событиями.
Напримерinput
Типtext
Используемый элемент формы:
value
onChange
дляtextarea
Этикетка также используется такvalue
а такжеonChange
:
<textarea value={this.state.value} onChange={this.handleChange} />
радио выбрать
дляselect
Для элементов формы,React
Можно и нативно превратить в управляемый компонентHTML
Есть некоторые отличия.
В нативном режиме мы по умолчаниюselect
опция проверена с помощью isselected
, например:
<select>
<option value="sunshine">阳光</option>
<option value="handsome">帅气</option>
<option selected value="cute">可爱</option>
<option value="reserved">高冷</option>
</select>
Дать"可爱"
Опция установленаselected
, он выбран по умолчанию.
Но если вы используетеReact
Контролируемые компоненты доставляют меньше хлопот, поскольку позволяютselect
используется на этикеткеvalue
свойства для управления тем, что выбрано. В данном случае нам тоже удобнее, нужно только обновлять его в корневом теге после каждого повторного выбора пользователем, как в этом случае 🌰:
class SelectComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: 'cute' };
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('你今日相亲对象的类型是: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={(e) => this.handleSubmit(e)}>
<label>
你今日相亲对象的类型是:
<select value={this.state.value} onChange={(e) => this.handleChange(e)}>
<option value="sunshine">阳光</option>
<option value="handsome">帅气</option>
<option value="cute">可爱</option>
<option value="reserved">高冷</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
}
export default SelectComponent;
можно ли увидетьinput
Типtext
Элементы управления по-прежнемуtextarea、select
в реализацииУправляемые компонентыЭто почти то же самое.
большой выбор
Большой выборselect
Если выбрано контраст, только эти два изменения:
- Дать
select
Настройки ярлыкаmultiple
собственностьtrue
-
select
Этикеткаvalue
Связанное значение представляет собой массив
Давайте просто напишем небольшой случай здесь:
class SelectComponent extends React.Component {
constructor(props) {
super(props);
// this.state = { value: 'cute' };
this.state = { value: ['cute'] };
}
handleChange(event) {
console.log(event.target.value)
const val = event.target.value;
const oldValue = this.state.value;
const i = this.state.value.indexOf(val);
const newValue = i > -1 ? [...oldValue].splice(i, 1) : [...oldValue, val];
this.setState({value: newValue});
}
handleSubmit(event) {
alert('你今日相亲对象的类型是: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={(e) => this.handleSubmit(e)}>
<label>
你今日相亲对象的类型是:
<select multiple={true} value={this.state.value} onChange={(e) => this.handleChange(e)}>
<option value="sunshine">阳光</option>
<option value="handsome">帅气</option>
<option value="cute">可爱</option>
<option value="reserved">高冷</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
}
export default SelectComponent;
(Но, оставаясь на Mac, Chrome, тестирующий этот множественный выбор, кажется проблематичным)
Динамический корпус компонента с контролируемой формой
Выше 👆 мы реализовали несколько простых случаев контролируемых компонентов, а затем воспроизвели чуть более сложный.
Давайте сначала посмотрим на наши потребности:
Реализуйте компонент, передайте следующий массив и автоматически отобразите форму:
(CInput
представляет поле ввода,CSelect
представляет поле выбора)
// 决定表单的结构
const formConfig = [
{
Component: CInput,
label: '姓名',
field: 'name',
},
{
Component: CSelect,
label: '性别',
field: 'sex',
options: [{ label: '男', value: 'man' }, { label: '女', value: 'woman' }]
}
]
// 决定表单的内容
this.state = {
name: '霖呆呆',
sex: 'man'
}
Эффект:
То есть реализовать простую динамическую форму и увидеть в ней применение управляемых компонентов.
-
formConfig
Определяет структуру формы, то есть определяет, какие элементы будут в форме -
this.state
определяет значение каждого элемента в форме, связанное сformConfig
зависит отformConfig
различныхfield
поле для установления связи.
Зная вышеизложенное 👆, мы можем быстро написать общий вид этого компонента динамической формы:
(Мы назвали этот компонент какformComponent
Ну сосредоточься наrender
часть)
import React, { Component } from 'react';
import { CInput, CSelect } from './components'
export default class FormComponent extends Component {
constructor (props) {
super(props);
this.state = {
name: '霖呆呆',
sex: 'man'
}
}
formConfig = [
{
Component: CInput,
label: '姓名',
field: 'name',
},
{
Component: CSelect,
label: '性别',
field: 'sex',
options: [{ label: '男', value: 'man' }, { label: '女', value: 'woman' }]
}
]
render () { // 重点在这
return (
<form style={{marginTop: '50px'}}>
{
this.formConfig.map((item) => { // 枚举formConfig
const { Type, field, name } = item;
const ControlComponent = item.Component; // 提取Component
return (
<ControlComponent key={field} />
)
})
}
</form>
)
}
}
можно увидеть,render
Вот некоторые из вещей, которые мы делаем:
- перечислить
formConfig
множество - извлечь каждый
Component
, присвоеноControlComponent
- визуализировать каждый элемент
Component
ControlComponent
Смысл переменной в том, чтобы сказатьReact
, какой компонент нужно отрендерить, еслиitem.Component
даCInput
, то окончательный рендеринг<CInput />
.
Это гарантирует, чтоformConfig
Каждый элемент формы в массиве визуализируется, но эти элементы формы по-прежнему находятся вне нашего контроля, нам нужно использовать то, что мы узнали ранее.value
а такжеonChange
и каждыйControlComponent
Сделайте соединение, например:
<ControlComponent
key={field}
name={field}
value={this.state[field]}
onChange={this.onChange}
{...item}
/>
мы кладемthis.state[field]
установлен вvalue
вверх, положитьthis.onChange
установлен вonChange
характеристики. (Как вы понимаете,CInput
а такжеCSelect
доступные компонентыthis.props
для получения входящих свойств, напримерthis.props.value
)
Тогда на этот разvalue
Установлено, что он изготовленthis.state[field]
решил, еслиfield
да"sex"
если,value
Значение"man"
.
так что посмотриonChange
Как написать метод:
onChange = (event, field) => {
const target = event.target;
this.setState({
[field]: target.value
})
}
Этот метод на самом деле очень прост, он принимаетevent
а такжеfield
,существуетevent
Вы можете получить значение, введенное/выбранное пользователем.
Хорошо 👌, давайте быстро посмотримCInput
а такжеCSelect
Как этого добиться:
components/CInput.jsx:
import React, { Component } from 'react';
export default class CInput extends Component {
constructor (props) {
super(props);
}
render () {
const { name, field, value, onChange } = this.props;
return (
<>
<label>
{name}
</label>
<input name={field} value={value} onChange={(e) => onChange(e, field)} />
</>
)
}
}
components/CSelect.jsx:
import React, { Component } from 'react';
export default class CSelect extends Component {
constructor (props) {
super(props);
}
render () {
const { name, field, options, value, onChange } = this.props;
return (
<>
<label>
{name}
</label>
<select name={field} value={value} onChange={(e) => onChange(e, field)}>
{options.length>0 && options.map(option => {
return <option key={option.value} value={option.value}>{option.label}</option>
})}
</select>
</>
)
}
}
Конечно, то, что здесь продемонстрировано, — это просто реализация динамической формы, если вы хотите реализовать ее в своем проекте, это намного сложнее, чем это.
неконтролируемые компоненты
Вышеприведенный 👆 показывает вам некоторые основные понятия и связанные с ними операции управляемых компонентов.Для управляемых компонентов нам необходимо状态更新
(Напримерthis.state.username
) написать事件处理程序
(Напримерthis.setState({ username: e.target.value })
).
Тогда есть другой сценарий: мы просто хотим получить значение элемента формы, и нам все равно, как оно изменится. Есть ли у нас способ справиться с этим сценарием🤔️?
Хорошо...input
ярлык это на самом деле тожеDOM
элемент, то можем ли мы получитьDOM
Информация об элементе способ получить значение элемента формы? то есть использоватьref
.
Так же, как этот случай ниже:
import React, { Component } from 'react';
export class UnControll extends Component {
constructor (props) {
super(props);
this.inputRef = React.createRef();
}
handleSubmit = (e) => {
console.log('我们可以获得input内的值为', this.inputRef.current.value);
e.preventDefault();
}
render () {
return (
<form onSubmit={e => this.handleSubmit(e)}>
<input defaultValue="lindaidai" ref={this.inputRef} />
<input type="submit" value="提交" />
</form>
)
}
}
После ввода содержимого в поле ввода нажмите кнопку отправки, мы можем пройтиthis.inputRef
успешно получилinput
изDOM
Информация о свойствах, включая введенные пользователем значения, поэтому нам не нужно поддерживать отдельное состояние для каждого элемента формы, как для контролируемого компонента.
Также мы можем использоватьdefaultValue
атрибут, чтобы указать значение по умолчанию для элемента формы.
тег файла специального файла
Также вinput
Есть и частный случай, т.file
Тип контроля формы.
Для элементов управления формы типа файл это всегда неуправляемый компонент, поскольку его значение может быть установлено только пользователем, а не программно.
Например, теперь я хочу управлять им с помощью обновлений состояния:
import React, { Component } from 'react';
export default class UnControll extends Component {
constructor (props) {
super(props);
this.state = {
files: []
}
}
handleSubmit = (e) => {
e.preventDefault();
}
handleFile = (e) => {
console.log(e.target.files);
const files = [...e.target.files];
console.log(files);
this.setState({
files
})
}
render () {
return (
<form onSubmit={e => this.handleSubmit(e)}>
<input type="file" value={this.state.files} onChange={(e) => this.handleFile(e)} />
<input type="submit" value="提交" />
</form>
)
}
}
После выбора файла я попытался использоватьsetState
Чтобы обновить, результат - ошибка:
Таким образом, мы должны использовать неуправляемый компонент, чтобы получить его значение, которое можно записать так:
import React, { Component } from 'react';
export default class FileComponent extends Component {
constructor (props) {
super(props);
this.fileRef = React.createRef();
}
handleSubmit = (e) => {
console.log('我们可以获得file的值为', this.fileRef.current.files);
e.preventDefault();
}
render () {
return (
<form onSubmit={e => this.handleSubmit(e)}>
<input type="file" ref={this.fileRef} />
<input type="submit" value="提交" />
</form>
)
}
}
получено здесьfiles
Это массив, конечно, если вы не включаете множественный выбор, длина этого массива всегда1
, очень просто открыть множественный выбор, просто добавьтеmultiple
свойства могут быть:
<input type="file" multiple ref={this.fileRef} />
Хорошо, я считаю, что у всех есть четкое представление об этих двух группах понятий. Какой? Вы спрашиваете меня реальный сценарий применения?
Ну... это, по официальным словам React, рекомендуется использовать большую часть времени受控组件
реализовать форму, потому что в контролируемом компоненте данные формыReact
Об этом позаботится компонент; конечно, если вы выберете受受控组件
Если данные формыDOM
разобраться с собой.
Кроме того, когда я изучал эти два, я также нашел несколько хорошо написанных статей, более подробных, чем эта, и рекомендую ее всем:
- "Как гибко использовать контролируемые и неконтролируемые компоненты в реальном бизнесе"
- «Размышляя об управляемых компонентах»
послесловие
Вы с нетерпением ждете мира, и я надеюсь, что у вас нет багов. Эта статья представлена здесь.
В основном, чтобы представить разницу и использование элементов управления и компонентов, не являющихся элементами управления, и, наконец,"重操旧业"
Начала писать статью, а сегодня неожиданно для себя обнаружила, что полугодовой итог Nuggets действительно в списке.Еще раз спасибо за щедрый лайк ❤️, ха-ха, я верю, что всем будет становиться все лучше и лучше!
Парень, которому нравится «Лин Дайдай», также надеется подписаться на публичный аккаунт Лин Дайдай LinDaiDai.
(Поскольку в последнее время я не могу опубликовать QR-код, извините за всех...)
Время от времени я буду обновлять некоторый внешний контент знаний и свои собственные оригинальные статьи🎉
Ваша поддержка - главная мотивация для меня продолжать творить 😊.
связанное предложение:
"Самый подробный учебник по bpmn.js во всей сети"
«[Предлагаемое изменение] Прочитав это, вы все еще не понимаете Вавилон, я пришлю вам маску»