const WelcomeComponent = (props) =>
<h1>Hello, {props.name}</h1>
class WelcomeComponent extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
const WelcomeComponent = (props) =>
<h1>Hello, {props.name}</h1>
const element = <WelcomeComponent name="Tele2" />
ReactDOM.render(
element,
document.getElementById('root')
)
https://abraxabra.ru/react.js/bystryy-start/react-js-komponenty-i-svoystva/
const Welcome = (props) =>
<h1>Hello, {props.name}</h1>
const App = (props) =>
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
ReactDOM.render(
<App />,
document.getElementById('root')
)
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
- Статья - https://reactjs.org/docs/state-and-lifecycle.html
- Пример - https://codepen.io/gaearon/pen/vXdGmd?editors=0010
- Статья - https://reactjs.org/docs/handling-events.html
- Пример - https://codepen.io/gaearon/pen/xEmzGg?editors=0010
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}
Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что нижележащая модель исполнения должна автоматически распространять изменения благодаря потоку данных.
К примеру, в императивном программировании присваивание a = b + c
будет означать, что переменной a будет присвоен результат выполнения операции b + c
, используя текущие (на момент вычисления) значения переменных. Позже значения переменных b
и c
могут быть изменены без какого-либо влияния на значение переменной a.
В реактивном же программировании значение a будет автоматически пересчитано, основываясь на новых значениях.
Пример - https://codepen.io/gaearon/pen/WZpxpz?editors=0010
- Вложенность - https://codepen.io/gaearon/pen/ozqNOV?editors=0010
- children в props - https://codepen.io/gaearon/pen/gwZOJp?editors=0010
- Динамические props https://codepen.io/gaearon/pen/kkEaOZ?editors=0010
- Мышление в React - https://abraxabra.ru/react.js/bystryy-start/myshlenie-v-react-js/
- !Как работать с JSX! - https://reactjs.org/docs/jsx-in-depth.html
- TODO MVC - http://todomvc.com/examples/react/#/
import React from 'react';
const MyComponents = {
DatePicker: function DatePicker(props) {
return <div>Imagine a {props.color} datepicker here.</div>;
}
}
function BlueDatePicker() {
return <MyComponents.DatePicker color="blue" />;
}
import PropTypes from 'prop-types';
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
Greeting.propTypes = {
name: PropTypes.string
};
Руководство по внедрению типизации - https://reactjs.org/docs/static-type-checking.html
import PropTypes from 'prop-types';
class Button extends React.Component {
render() {
return (
<button style={{background: this.context.color}}>
{this.props.children}
</button>
);
}
}
Button.contextTypes = {
color: PropTypes.string
};
class Message extends React.Component {
render() {
return (
<div>
{this.props.text} <Button>Delete</Button>
</div>
);
}
}
class MessageList extends React.Component {
getChildContext() {
return {color: "purple"};
}
render() {
const children = this.props.messages.map((message) =>
<Message text={message.text} />
);
return <div>{children}</div>;
}
}
MessageList.childContextTypes = {
color: PropTypes.string
};
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
Используются при необходимости рендера вне заданной структуры DOM. Документация. https://reactjs.org/docs/portals.html
Тестовое задание - https://redux.js.org/basics/example-todo-list Материалы для самостоятельного изучения - https://rajdee.gitbooks.io/redux-in-russian/content/docs/introduction/Ecosystem.html
Глоссарий - https://rajdee.gitbooks.io/redux-in-russian/content/docs/Glossary.html
- Состояние (State)
- Действие (Action) - Вызов функции изменения состояния
- Редюсер (Reducer) - Функция которая изменяет состояние
- Функция-диспетчер (Dispatching Function) - It refers to the control of processes of operation planning, giving operation order and controlling operations in the manufacturing site.
- Генератор действия (Action Creator) - Фабрика для создания actions
- Асинхронное действие (Async Action) -
Promise
например. - Мидлвэр (Middleware) - функция высшего порядка, которая создает функцию-диспетчер (dispatch function), возвращающую новую функцию-диспетчер.
- Хранилище (Store)
- Генератор хранилища (Store creator)
- Расширитель хранилища (Store enhancer) - см. middleware
3 принципа - https://rajdee.gitbooks.io/redux-in-russian/content/docs/introduction/ThreePrinciples.html
- Source of truth - Состояние всего вашего приложения сохранено в дереве объектов внутри одного хранилища.
- Change action - Единственный способ изменить состояние — это применить действие — объект, который описывает, что случится.
- Clean functions - Для определения того, как дерево состояния будет трансформировано действиями, вы пишете чистые редюсеры.
Reducer — это просто чистые функции, которые берут предыдущее состояние и действие и возвращают новое состояние. Не забывайте возвращать новый объект состояния вместо того, чтобы изменять предыдущее.
Связь React & Redux
import React from 'react'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { Link } from 'react-router-dom'
class Navigation extends React.Component {
componentWillMount() {
this.props.getProfileInformation()
}
routes() {
return [
{
route: '/profile/password',
name: 'Изменение пароля'
},
{
route: '/profile/info',
name: 'Профиль'
}
]
}
render () {
return (
const { userName } = this.props
<Container>
{ userName }
<div>
{
this.routes().map((item, i) =>
<NavLink to={item.route} key={i}>
{item.name}
</NavLink>
)
}
</div>
</Container>
)
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
getProfileInformation,
}, dispatch)
const mapStateToProps = store => ({
userName: store.profile.name
})
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Navigation))