React.js. Однонаправленный поток данных
28.07.2021
Теги: Frontend • JavaScript • React.js • Web-разработка • Иерархия • Функция
В реакте поток данных — однонаправленный. Это значит, что данные передаются как водопад, сверху вниз, от родителя к ребенку, через props. При этом props — неизменяемый объект, предназначенный только для чтения. Проще понять, если думать о компонентах, как о функциях (а они по сути ими и являются). Тогда props — это просто аргумент функции, с которым мы можем работать внутри, но не можем изменять.
Родитель → Ребенок — используем props
Это самый простой способ передачи данных:
- В родительском компоненте передаём данные из
state
в дочерний - В дочернем компоненте принимаем и передаем в следующий дочерний
- В последнем дочернем компоненте принимаем и просто выводим
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