Оригинальная ссылка:учись реагировать.дизайн/2018/01/15/…
Нравится причина: письмо яркое и легкое для понимания
Особая благодарность: оригинальному авторуLinton Yeлюблю корректуру
Серия блогов: Объяснение терминологии React с точки зрения непрофессионала и каракулей
- Графический ответ
- Графический React Native
- Компоненты, свойства и состояние
- Глубокое понимание свойств и состояния (эта статья)
- React Native против Cordova, PhoneGap, Ionic и других(для перевода)
существуетПредыдущая статьяВ , мы представили компоненты, свойства и состояние.
Разница между свойствами и состоянием довольно очевидна, и определение того, когда использовать свойства и состояние, кажется простым. Например, цвет крыши естественно опорный, потому что цвет является неотъемлемым свойством крыш. С другой стороны, открытое и закрытое состояние двери, очевидно, является состоянием, потому что дверь также может быть открыта или закрыта после ее создания. Однако в этой статье мы бросаем вызов такому образу мышления в будущем!
без шуток? ! ? Верно, то, что вы видите, может быть как реквизитом, так и состоянием. Абсолютных границ нет. Я представлю более полезный и практичный подход к свойствам и состоянию.
цель обучения
Надеюсь, вы вернетесь сюда, когда закончите читать эту статью, и сможете легко ответить на следующие вопросы:
- Каково основное назначение props и state?
- Что означает «государственное продвижение»? В каких сценариях вам нужно улучшить состояние?
новый участник
Вы заметили новых участников вокруг дома? Попробуйте щелкнуть дверью!
Вид на фокусировщик (@focuser) существуетCodePenНаписанная демонстрация:React Shack с кошками.
Это сонная кошка, она спит, когда дверь закрыта, и встает только тогда, когда дверь снова открывается. Если дверь закрывалась, она тут же снова засыпала.
Реализовать кошку
Теперь я спрашиваю вас, понимаете ли вы поведение кошки? Первый, чтобы попробовать это!
Начните с «кода» ниже и найдите время, чтобы сначала прочитать его. (Опять же, это не настоящий код JavaScript, это просто упрощенная форма, которая поможет вам понять концепции, не отвлекаясь на детали JS.)
House:
<div>
<Roof />
<Wall />
<Window />
<Door />
<Cat />
</div>
Door:
State: status <!-- "open" 或 "closed" -->
<div>{state.status} door</div>
当点击门时
如果 door.state.status 为 "open"
将 door.state.status 修改成 "closed"
否则
将 door.state.status 修改成 "open"
существуетHouse
компонент добавленCat
Этикетка. ТакCat
Что насчет компонентов? Давайте определим это.
Кошки либо спят, либо просыпаются. Это очень похоже на открытие и закрытие двери. Возможно, мы также можем использовать состояние для представления состояния кота:
Cat:
State: status <!-- "sleeping" 或 "awake" -->
<div>{state.status} cat</div>
Cat
После того, как компонент определен, все, что нужно реализовать, — это синхронизировать состояние кота и двери. Мы хотим, чтобы кошка находилась в состоянии «бодрствования», когда дверь открыта, и «спала» в противном случае.
Это так просто? Слушай, давай поговорим...
первая попытка
Теперь, когда у нас есть код для переключения состояния двери в зависимости от текущего состояния, давайте изменим состояние кота здесь:
Door:
State: status <!-- "open" 或 "closed" -->
<div>{state.status} door</div>
当点击门时
如果 state.status 为 "open"
将 state.status 修改成 "closed"
将 cat.state.status 修改成 "sleeping" <!-- 错误的 -->
否则
将 state.status 修改成 "open"
将 cat.state.status 修改成 "awake" <!-- 错误的 -->
К сожалению, это не работает! Помните, что состояние компонента — это частные данные? Доступен только внутри компонента. Никакие другие компоненты, будь то родительские или одноуровневые, не могут получить доступ к состоянию этого компонента.
К сожалению, мыDoor
Попытки изменить состояние кота внутри компонента не увенчались успехом. (преобразование в реальный код JavaScript не является исключением)
вторая попытка
затем вCat
Как насчет изменения состояния кота внутри компонента? На этот раз должно сработать, верно?
Cat:
State: status <!-- "sleeping" 或 "awake" -->
<div>{state.status} cat</div>
当点击门时 <!-- 黑人门号脸???怎么个点击法? -->
如果 door.state.status 为 "open" <!-- 错误的 -->
将 cat.state.status 修改成 "sleeping"
否则
将 cat.state.status 修改成 "awake"
без сомнения, вCat
Не проблема изменить состояние кота внутри компонента. Но нам нужно прочитать состояние двери, чтобы решить, в каком состоянии кот. Состояние двери такоеDoor
состояние компонента, поэтому его нельзя использовать вCat
Доступ в компоненте!
Решение
Эм-м-м! Такой хромой. Чтобы синхронизировать состояние двери и кота, нам нужно где-то иметь доступ к обоим. Но оказывается, что данные скрыты от внешнего мира намеренно. Как решить эту проблему?
Решение состоит в том, что нам нужно гибко понимать использование состояния и свойств.
состояние задней двери
House
Компоненты:
House:
<div>
...
<Door />
<Cat />
</div>
Door
а такжеCat
размещаются рядом. Может быть, здесь их можно легко синхронизировать?
Но мы сейчасHouse
внутри компонента. Как и в предыдущих попытках, здесь нет возможности читатьDoor
Или изменение состоянияCat
штат .
Но что, если мы используем свойства вместо состояния?
House:
<div>
...
<Door status="open" />
<Cat status="awake" />
</div>
Когда дверь закрыта:
House:
<div>
...
<Door status="closed" />
<Cat status="sleeping" />
</div>
Конечно, состояние ворот не будет фиксированной величиной, оно будет меняться со временем. мы используемdoorStatus
для обозначения состояния двери.
House:
<div>
...
<Door status={doorStatus} />
<Cat status={如果 doorStatus 为 'open' 值为 'awake' 否则为 'sleeping'} />
</div>
Разве это не решает проблему синхронизации? Кстати, это значение изменитсяdoorStatus
что это такое? Что можно изменить в компоненте? Правильно, это состояние.
House:
State: doorStatus <!-- 'open' 或 'closed' -->
<div>
...
<Door status={state.doorStatus} />
<Cat status={如果 state.doorStatus 为 'open' 值为 'awake' 否则为 'sleeping'} />
</div>
чудесный!House
Компоненты теперь четко определены, а состояние двери и кота идеально синхронизировано.
Нам также необходимо изменитьDoor
а такжеCat
Компоненты, используйте свойства вместо состояния:
Door:
<div>{props.status} door</div>
Cat:
<div>{props.status} cat</div>
Как видите, поскольку мы хотим использовать состояние родительского компонента, в данном случае для установки состояния кота состояние двери фактически получается изHouse
Да, мы можем представить те же данные, что и состояние родительского компонента, и передать данные дочернему компоненту в качестве реквизита. Обычно это называется поднятием состояния. Мы перемещаем состояние на более высокий уровень в компоненте.
Изменить состояние дома
Теперь состояние двери и кота связано через состояние дома. Если мы хотим открыть дверь или разбудить кошку, нам нужно изменитьHouse
Состояние компонента.
Вопрос в том, где единственный способ обновитьHouse
состояние места? вHouse
В компоненте, верно?
Однако мы хотимDoor
чтобы вызвать это изменение. То есть эффект, который мы хотим, состоит в том, чтобы открывать дверь только при нажатии на дверь, а не весь дом или окна и т. д.
такDoor
Компоненты нуждаются в некоторых изменениях:
Door:
<div>{props.status} door</div>
当点击门时
做某件事来修改 `House` 的 state
Но подождите, я не могDoor
Внутрикомпонентная модификацияHouse
состояние?
Вот так. Мы не можем напрямую изменитьHouse
штат . Но это не значит, что его нельзя изменить косвенно. смотреть вниз…
существуетHouse
Внутри компонента давайте напишем код для фактического изменения его состояния:
House:
State: doorStatus <!-- 'open' 或 'closed' -->
toggleDoorStatus:
如果 state.doorStatus 为 'open'
将 state.doorStatus 修改成 'closed'
否则
将 state.doorStatus 修改成 'open'
...
На данный момент мы не указали, когда запускать этот код. Мы просто дали ему имя (toggleDoorStatus
), чтобы найти его позже по имени для запуска.
потомtoggleDoorStatus
передано в качестве реквизитаDoor
Компоненты:
House:
...
<div>
...
<Door ... onClickAction={toggleDoorStatus} />
...
</div>
существуетDoor
компонент, нам просто нужно выполнить это действие щелчка:
Door:
<div>{props.status} door</div>
当点击门时
执行 props.onClickAction <!-- 实际运行的是名为 "toggleDoorStatus" 的代码-->
Это как передать кому-то пульт от телевизора. кто-тоDoor
Кнопка дистанционного управления была нажата внутри компонента.House
Телевизор в комплекте переключает каналы или увеличивает громкость.
что произойдет, зависит от прохода кDoor
Что за пульт. Это может быть управление телевизором, кондиционером или аудиосистемой в комнате. существуетDoor
Внутри сборки все, что нужно сделать, это нажать кнопку на пульте дистанционного управления.
Это то, что нам нужно! Вот полный "код":
House:
State: doorStatus <!-- 'open' or 'closed' -->
toggleDoorStatus:
如果 state.doorStatus 为 'open'
将 state.doorStatus 修改成 'closed'
否则
将 state.doorStatus 修改成 'open'
<div>
...
<Door status={state.doorStatus} onClickAction={toggleDoorStatus} />
<Cat status={如果 state.doorStatus 为 'open' 值为 'awake' 否则为 'sleeping'} />
</div>
Door:
<div>{props.status} door</div>
当点击门时
执行 props.onClickAction
Cat:
<div>{props.status} cat</div>
Второй взгляд на свойства и состояние
Теперь давайте вернемся к нескольким вопросам: в чем разница между props и state? Когда следует использовать состояние? Когда следует использовать реквизит?
Когда использовать состояние? Когда использовать реквизит?
Если вы помните, я уже говорил, что props — это неотъемлемое свойство компонента, оно не изменится, пока состояние создано после некоторых компонентов, его можно изменить. При первом изучении этих двух концепций это полезно.
Однако пример, который мы только что создали, подтверждает это представление. Будь то открытие двери или засыпание кота, это должно быть State, но мы используем PROPS для их представления. почему это?
Оказывается, в выборе состояния и реквизита еще много гибкости. В зависимости от того, как вы на это смотрите, вы можете моделировать компонент по-разному. Например, когда дверь открыта, вы можете сказать, что это состояние двери, вы можете сказать, что это состояние дома.
более удобный способ понимания
Смущенный? Вот более полезный способ осмысления проблемы:
- Состояние: если пользовательский интерфейс нужно изменить, это означает, что где-то должно быть состояние.
- Реквизит: используется для передачи данных, управления передачей
Когда приложение работает, если пользовательский интерфейс нужно изменить, он должен быть в состоянии. Когда дверь нажимается, дверь либо открывается, либо закрывается, тогда это должно быть где-то состояние.
Однако государство не обязательно является состоянием обновленного компонента. Это может быть в некотором компонентах вверх по течению. Все зависит от того, где и как нам нужно использовать эту информацию. В качестве примера мы решили изменить состояние двери изDoor
компоненты продвигаются наHouse
компонент, потому что нам нужноHouse
Компоненты используют его.
С другой стороны, реквизиты — это просто вещи, используемые для передачи данных. так как ранее мы изменили состояние двери сHouse
компонент передается наDoor
компоненты.
Он также может быть использован для передачи контроля. Например, мы подойдем к мероприятиюHouse
перейти кDoor
.
Изменит ли реквизит в этом примере значение?
Нет, реквизит никогда не меняет значение. Я понимаю, что вы имеете в виду, дверь открывается и закрывается, а кот спит и просыпается. Поскольку мы теперь используем пропсы для их представления, легко подумать, что пропсы ведут себя как состояния, и их значения меняются, верно?
Это просто иллюзия, и я обнаружил, что она очень похожа на анимацию в книжке-книжке.
Каждый раз, когда состояние дома меняется, старый кот исчезает, а затем воссоздается кот с совершенно новым состоянием. Но этот процесс происходит так быстро, что у нас остается остаточное видение спящего и просыпающегося там кота.
Эскизы на любой странице флипбука не будут перемещаться. Точно так же каждая кошка остается бодрствующей/сонной на протяжении всей своей (короткой) жизни.
Суммировать
Что ж, мы снова изучили props и state на более сложном примере. В этом примере, когда дверь щелкнута, дверь должна переключить состояние переключателя, и нам также нужно синхронизировать состояние двери и кота,
Поскольку состояние является частным, нам нужно изменить состояние ворот сDoor
компоненты продвигаются наHouse
в компоненте. то что мы можемHouse
Эти данные используются в компоненте для установки состояния двери и кота. Мы передаем эти данные в качестве реквизитаDoor
а такжеCat
, чтобы они отображали правильное изображение в зависимости от состояния двери.
Другим требованием является инициация изменения состояния при нажатии на дверь. Потому что теперь состояние двериHouse
состояние, которое является частными данными и может использоваться только вDoor
компонент, чтобы изменить его косвенно. мы вHouse
Код, который фактически изменяет состояние, записывается в компоненте, который затем передается в качестве реквизита вDoor
. Это похоже на передачу кому-то пульта от телевизора.
Примеры в этой статье могут вас немного смутить. Вот более практичный способ думать о свойствах и состоянии:
- Состояние: если пользовательский интерфейс нужно изменить, это означает, что где-то должно быть состояние.
- Реквизит: используется для передачи данных, управления передачей
Как вы себя чувствуете? Если у вас есть какие-либо вопросы или комментарии, пожалуйста, напишите мне!