SocialNetworkReact
Social Network on React
Install / Use
/learn @Ynhito/SocialNetworkReactREADME
React
##Дисклеймер Всё, что написано далее написано мною лично. Я постарался донести всю информацию максимально понятным языком. Делал я это в первую очередь для себя, чтобы лучше усвоить информацию, так что в некоторых моментах я писал вещи понятные только мне.
Компонента
Компонента - это функция, которая возвращает JSX разметку. Т.е HTML внутри JS. Компоненту никогда не вызывают, Компонента - это ТЕГ.
SPA
SPA - <u>Single page application</u> (Всё происходит в одном HTML файле, который приходит пользователю)

Пропсы
Пропсы - произвольные данные(объекты), которые задаются в виде атрибута ТЕГА(компоненты) и хранятся в объекте под видом Ключ : Значение (например
<Welcome name="Dima" />
имеет вид находясь в объекте, который в свою очередь является параметром функции:
props {
name : "Dima"
}
Модуль react-router-dom
позволяет использовать route (изначально всё нужно обвернуть в один блок под названием BrowserRouter. Он позволяет отрисовывать компоненты, отслеживания их url (
react <Route path='/profile' component={Profile} />
).
Чтобы задать изменение url нужно использовать тег NavLink (
```react
<NavLink to="/profile">
Profile
</NavLink>
```
)
BLL (Business Logic Layer) - REDUX UI (User Interface) - REACT
Метод для массива MAP
Пример использования: Объявляем массив с объектами, содержащими ключ и значение
let messagesData = [
{id: 1, message: 'Hello'},
{id: 2, message: 'Privet'},
{id: 3, message: 'Aloha'},
];
Создаём новый массив и делаем его равным массиву messagesData с методом map. Параметром будет являться каждый объект массива messagesData. Назовём его просто - d.
let dialogsElement = dialogsData
.map(d => <DialogItem name={d.name} id={d.id} />);
onClick, ref, VirtualDOM
OnClick
Атрибут OnClick к тегу звучит как "Действие по клику"
<button *onClick*={addPost}>Отправить</button>
Значением этого атрибута может служить анонимная функция, либо же CallBack функция.
CallBack
CallBack функция - это функция обратного вызова. Т.е функция, которая вызывается другой функцией.
Например. Создали функцию:
`let addPost = () => { ` `
`alert(text);`
`}`
Мы можем вызвать её стандартным способом addPost(). Либо же передать её внутрь другой функции
<button *onClick*={addPost}>Отправить</button>
БЕЗ СКОБОК!!!
ref
<textarea *ref*={newPostElement}></textarea>
ref - это ссылка. Это тоже самое, что присвоить элементу id или класс.
Команда ниже аналогична команде
let newPostElement = document.getElementById('id')
let newPostElement = React.createRef();
Но с помощью инструментов React. Это нужно потому, что нельзя обращаться напрямую к DOM.
Взаимодействовать с ссылками можно таким образом:
let text = newPostElement.current.value;
VirtualDOM
React работает с VirtualDOM. Он подгружает компоненты <u>постепенно</u> в DOM, а поэтому мы не можем знать существует ли данный элемент, к которому мы обращаемся, в DOM.
ReRender

Файл render.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {addPost} from './redux/state';
import {BrowserRouter} from 'react-router-dom';
export let reRenderEntireTree = (state) => {
ReactDOM.render(
<BrowserRouter>
<App state={state} addPost={addPost} />
</BrowserRouter>, document.getElementById('root'));
}
Файл state.js:
import {reRenderEntireTree} from "../render";
let state = {...}
export let addPost = (postMessage) => {
let newPost = {
id: 3,
message: postMessage,
};
state.profile.postsData.push(newPost);
reRenderEntireTree(state);
}
export default state;
Файл index.js:
import './index.css';
import * as serviceWorker from './serviceWorker';
import {reRenderEntireTree} from "./render";
import state from './redux/state';
reRenderEntireTree(state);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
FLUX Концепция/Архитектура

Концепция звучит так: Изменения в UI мире должны происходить только тогда, когда произойдут изменения в BLL мире
P.S,
Action - действия/изменения,
state inside props - новые данные stat'a передаваемые в UI с помощью пропсов
Инкапсулировать детали - скрыть детали/скрыть логику
Store
Псевдо ООП
import profileReducer from "./profile-reducer";
import messagesReducer from "./messages-reducer";
import friendsReducer from "./friends-reducer";
let store = {
_state: {
profile: {
postsData: [
{ id: 1, message: 'Hi, how are you' },
{ id: 2, message: 'Its my first post' }
],
newPostText : ''
},
messages: {
dialogsData: [
{ id: 1, name: 'Dima' },
{ id: 2, name: 'Julia' },
{ id: 3, name: 'Victor' },
{ id: 4, name: 'Sasha' }
],
messagesData: [
{ id: 1, message: 'Hello' },
{ id: 2, message: 'Privet' },
{ id: 3, message: 'Aloha' }
],
newMessageText : ''
},
friends: {
friendsData: [
{ id: 1, name: 'Dima' },
{ id: 2, name: 'Julia' },
{ id: 3, name: 'Victor' }
]
}
},
_callSubscriber() {
console.log("state changed")
},
getState() {
return this._state;
},
subscribe(observer) {
this._callSubscriber = observer;
},
dispatch(action) { //action === actionCreator (EX. addPostActionCreator)
this._state.profile = profileReducer(this._state.profile, action);
this._state.messages = messagesReducer(this._state.messages, action);
this._state.friends = friendsReducer(this._state.friends, action);
this._callSubscriber(this._state);
}
}
export default store;
window.store = store;
Перерисовка
Файл index.js
import './index.css';
import * as serviceWorker from './serviceWorker';
import store from './redux/redux-store';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {BrowserRouter} from 'react-router-dom';
let reRenderEntireTree = (state) => {
ReactDOM.render(
<BrowserRouter>
<App state={state} dispatch={store.dispatch.bind(store)} store={store}/>
</BrowserRouter>, document.getElementById('root'));
}
reRenderEntireTree(store.getState());
store.subscribe(() => {
let state = store.getState();
reRenderEntireTree(state);
});
reRenderEntireTree - Функция, которая рисует ui с помощью ReactDOM.render.
В этом же файле мы её вызываем, чтобы при первом запуске страницы увидеть ui
reRenderEntireTree(store.getState());
НО, UI должен перерисовываться каждый раз, когда он изменяется. Для этого мы обращаемся к функции subscribe через store. И передаём ей в качестве параметра reRenderEntireTree со state в параметре.
store.subscribe(() => {
let state = store.getState();
reRenderEntireTree(state);
});
Функция subscribe имеет параметр observer, который по выполнению функции должен стать равным другой пустой функции callSubscriber которая в свою очередь уже не становится пустой.
subscribe(observer) {
this._callSubscriber = observer;
},
Было:
_callSubscriber() {
console.log("state changed")
}
Стало:
_callSubscriber() {
let state = store.getState();
reRenderEntireTree(state);
}
Как только (например по нажатию кнопки) в dispatch приходит action происходит вызов callSubscriber (отсюда и название функции)
dispatch(action) { //action === actionCreator (EX. addPostActionCreator)
this._state.profile = profileReducer(this._state.profile, action);
this._state.messages = messagesReducer(this._state.messages, action);
this._state.friends = friendsReducer(this._state.friends, action);
this._callSubscriber(this._state);
}
Происходит перерисовка UI.
Bind()
Метод bind() создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения this предоставленное значение.
Для чего он нужен? Например, если у нас есть функция
_addPost() {
let newPost = {
id: 3,
message: this._state.profile.newPostText,
};
this._state.profile.postsData.push(newPost);
this._state.profile.newPostText ='';
this._callSubscriber(this._state);
},
И мы передаём её в пропсы как callback
addPost={store.addPost}
То при использовании(вызове) мы будем обращаться к ней от имени(внутри объекта) props
props.addPost()
В этом случае все this будут обращаться именно к props. Ближайшему родительскому объекту, а не к _state, как это было задумано. Что вызывает ошибку.
В этой то ситуации мы и используем bind(Объект на который мы хотим сослаться)
addPost={store.addPost.bind(store)
Dispatch, Action, ActionCreator, Reducer
dispatch - это метод(функция), который передаёт action(действие) в reducer.
dispatch(sendMessageActionCreator());
Action - это объект, который содержит минимум type
ActionCreator - это фу
