React.js. Однонаправленный поток данных

28.07.2021

Теги: FrontendJavaScriptReact.jsWeb-разработкаИерархияФункция

В реакте поток данных — однонаправленный. Это значит, что данные передаются как водопад, сверху вниз, от родителя к ребенку, через props. При этом props — неизменяемый объект, предназначенный только для чтения. Проще понять, если думать о компонентах, как о функциях (а они по сути ими и являются). Тогда props — это просто аргумент функции, с которым мы можем работать внутри, но не можем изменять.

Родитель → Ребенок — используем props

Это самый простой способ передачи данных:

  1. В родительском компоненте передаём данные из state в дочерний
  2. В дочернем компоненте принимаем и передаем в следующий дочерний
  3. В последнем дочернем компоненте принимаем и просто выводим
import React from 'react';
import {Posts} from './components/Posts';

class App extends React.Component {
    state = {
        posts: [
            {id: '123', name: 'Пост раз', body: 'Lorem ipsum dolor sit amet'},
            {id: '456', name: 'Пост два', body: 'Lorem ipsum dolor sit amet'},
            {id: '789', name: 'Пост три', body: 'Lorem ipsum dolor sit amet'},
        ],
    };

    render() {
        return (
            <div className="App">
                <Posts posts={this.state.posts} />
            </div>
        );
    }
}

export default App;
import React from 'react';
import {Post} from './Post';

export function Posts(props) {
    return (
        <div>
            {props.posts.map(post => 
                <Post
                    key={post.id}
                    id={post.id}
                    name={post.name}
                    body={post.body}
                />
            )}
        </div>
    );
}
import React from 'react';

export function Post(props) {
    const {id, name, body} = props;
    return (
        <div>
            <h2>{name}</h2>
            <p>{body}</p>
        </div>
    );
}

Родитель ← Ребенок — используем callback

Эта передача данных напоминает бумеранг, есть точка старта — это наш родительский компонент, есть точка максимального отдаления — это потомок. И есть наш инструмент — бумеранг, в реакт это будет функция, которая находится в родителе и передаётся через props потомку, где и вызывается.

import React from 'react';
import {Posts} from './components/Posts';

class App extends React.Component {
    state = {
        posts: [
            {id: '123', name: 'Пост раз', body: 'Lorem ipsum dolor sit amet'},
            {id: '456', name: 'Пост два', body: 'Lorem ipsum dolor sit amet'},
            {id: '789', name: 'Пост три', body: 'Lorem ipsum dolor sit amet'},
        ],
    };

    removePost = (id) => {
        this.setState({posts: this.state.posts.filter(post => post.id !== id)});
    }

    render() {
        return (
            <div className="App">
                <Posts posts={this.state.posts} remove={this.removePost} />
            </div>
        );
    }
}

export default App;
import React from 'react';
import {Post} from './Post';

export function Posts(props) {
    return (
        <div>
            {props.posts.map(post => 
                <Post
                    key={post.id}
                    id={post.id}
                    name={post.name}
                    body={post.body}
                    remove={props.remove}
                />
            )}
        </div>
    );
}
import React from 'react';

export function Post(props) {
    const {id, name, body, remove} = props;
    return (
        <div>
            <h2>{name}</h2>
            <p>{body}</p>
            <button onClick={() => remove(id)}>Удалить</button>
        </div>
    );
}

Ребенок → Ребенок — используем родителя

Для того, чтобы передать данные между сестринскими компонентами, нужно использовать посредника — их родителя. Сначала нужно передать данные от ребенка к родителю как аргумент коллбека. Потом присвоить эти данные в state родителя и передать через props другому компоненту.

Вместо заключения

В иерархии компонентов ни родительский, ни дочерние компоненты не знают, задано ли состояние другого компонента. Также не важно, как был создан определённый компонент — с помощью функции или с помощью класса. Состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. Состояние всегда принадлежит определённому компоненту, а любые производные этого состояния могут влиять только на компоненты, находящиеся «ниже» в дереве компонентов.

Поиск: JavaScript • React.js • Web-разработка • Frontend • Иерархия • Функция • Callback • Props

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.