SkillAgentSearch skills...

SocialNetworkReact

Social Network on React

Install / Use

/learn @Ynhito/SocialNetworkReact
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

React

##Дисклеймер Всё, что написано далее написано мною лично. Я постарался донести всю информацию максимально понятным языком. Делал я это в первую очередь для себя, чтобы лучше усвоить информацию, так что в некоторых моментах я писал вещи понятные только мне.

Компонента

Компонента - это функция, которая возвращает JSX разметку. Т.е HTML внутри JS. Компоненту никогда не вызывают, Компонента - это ТЕГ.

SPA

SPA - <u>Single page application</u> (Всё происходит в одном HTML файле, который приходит пользователю)

1562585643793

Пропсы

Пропсы - произвольные данные(объекты), которые задаются в виде атрибута ТЕГА(компоненты) и хранятся в объекте под видом Ключ : Значение (например

<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

1562938967001

Файл 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 Концепция/Архитектура

1562940934753

Концепция звучит так: Изменения в 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 - это фу

View on GitHub
GitHub Stars132
CategoryDevelopment
Updated1d ago
Forks23

Languages

JavaScript

Security Score

80/100

Audited on Mar 26, 2026

No findings