Вопрос №50402 от пользователя Артём в уроке «React Redux», курс «JS: Redux (React)»

Артём

Если мы создаём компонент как класс, то в случае необходимости повесить на какой-либо элемент обработчик с созданной внутри компонента функцией мы пишем onClick={this.onClickFunction}, но если компонент реализован как функция - то пишем onClick={onClickFunction}. По крайней мере именно это я вижу в решении. Внимание, вопрос - где об этой разнице говорилось в учебном материале?

И ещё вопрос, не могу сам раскопать, так же два компонента - через класс и через функцию. Если компонент функциональный, то ему на входе можно передать все необходимые пропсы, и через деструктуризацию использовать сразу в функциях, вот так

const someComponents = ({ someStatePart, someFunction1, someFunction2}) => {
  //какой-то код
  какая-то_функция_1 (e) {
   someFunction1(e.target.value)
  };

  какая-то_функция_2 (e) {
   someFunction2(e.target.value)
  };
 }

в то время как в компоненте через класс, мы в каждой функции внутри компонента выдёргиваем нужные нам константы

class SomeComponent extends React.Component {
  какая-то_функция_1 = (e) => {
    const { someFunction1 } = this.props;
    someFunction1(e.target.value);
  };

  какая-то_функция_2 = (e) => {
    const { someFunction2 } = this.props;
    someFunction2(e.target.value);
  };


}

и так до бесконечности, внутри каждой функции что-то дёргается из this.props. Можно ли как-то сразу вкинуть всё необходимое, как в случае с функциональным компонентом?

7 0

Сергей Мелодин

Артём, приветствую.

Если мы создаём компонент как класс

Функциональный компонент - это такая же функция, как эта:

const sum = (a, b) => {
  return a + b;
};

Если вы обратитесь внутри к this внутри неё, то получите ошибку. Работа с this и классами разбиралась ранее, если вы понимаете, что что-то упустили - лучше вернуться и повторить, так как это достаточно важная тема.


что-то дёргается из this.props

Опять же, речь про понимание отличий функции от класса. Пропсы в данном случае попадают в конструктор класса и в каждом методе вы обращаетесь к this, потому что иначе никак. В случае функционального компонента, пропсы - это параметры функции.

0

Артём

Сергей Мелодин, Спасибо за ответ.

Но появились ещё вопросы( я например в упор не понимаю, откуда mapStateToProps берёт state, который получает на входе. В теории написано "состояние из контейнера", контейнер в данном случае это Provider? А переданный в него store и есть состояние, которое каким-то магическим образом само попадает на вход mapStateToProps? Я не вижу в принципе никаких state в решениях, где присутствует mapStateToProps.

0

Сергей Мелодин

Артём, код в теории отображает два файла, поэтому чтобы разобраться, надо смотреть и в теорию, и в исходники: connect получает mapStateToProps https://github.com/reduxjs/react-redux/blob/master/src/connect/connect.js#L53-L54 и возвращает функцию https://github.com/reduxjs/react-redux/blob/master/src/connect/connect.js#L78 в которую передаётся компонент, как показано в теории. Всё это экспортируется наружу, как TasksBox. А далее, когда мы уже обращаемся к компоненту через провайдера, происходит прокидывание стейта в пропсы примерно таким образом: https://github.com/reduxjs/react-redux/blob/48773fdb28b341f3fd7e9c6cb48cfaad6a471b6d/src/components/connectAdvanced.js#L158-L161

Я не вижу в принципе никаких state в решениях, где присутствует mapStateToProps.

В этом и суть, что всё абстрагировали и спрятали за сотнями строк кода.

0

Артём

Сергей Мелодин, а вот здесь понимания не прибавилось ни на грамм(

0

Roman Makarov

Артём, добрый день!

mapStateToProps - это функция, которую определяете вы и которая будет вызвана библиотекой внутри функции connect. Ожидается, что функция mapStateToProps будет иметь определённый интерфейс - принимать в качестве аргумента state. Библиотека react-redux вызывает эту функцию и передаёт в неё state (store !== state, вспомните, как формируется стор?) Механизм примерно такой: connect принимает на вход компонент и функцию для обработки стейта (mapStateToProps), и возвращает компонент, в пропсы которого прокинут обработанный стейт. Назначение этих манипуляций описано в теории урока. Помимо прокидывания пропсов, connect подписывает компоненты на изменения стора и может прокидывать в пропсы функции для диспатча экшнов (mapDispatchToProps).

0

Артём

Roman Makarov, "вызывает эту функцию и передаёт в неё state" - откуда берётся этот state? я всё ещё не получил вразумительного ответа на этот вопрос. у нас есть только store в Provider, и всё. Вот как всё выглядит в конечном файле

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('container'),
);

но вы пишете что store !== state. а в последнем задании(Структура состояния) ещё и началась путаница с тем, что должно возвращаться из этой функции. Сначала мы возвращали просто нужную часть state, вот так

const mapStateToProps = (state) => {
  const { tasks } = state;
  return { tasks };
};

а в упомянутом выше задании я вижу вот что:

  const { tasks: { byId, allIds } } = state;
  const tasks = allIds.map((id) => byId[id]);
  return { tasks };

сказать, что я поплыл - ничего не сказать.

0

Roman Makarov

Артём,

откуда берётся этот state?

Из стора, который вы создали и передали в Provider. Provider - это часть библиотеки react-redux, как и connect. Ещё раз - вы не вызываете функцию mapStateToProps, за вас это делает библиотека react-redux, вы можете только определить эту функцию, соблюдая при этом определённую сигнатуру, а именно: функция принимает state и возвращает объект с данными, которые будут переданы в пропсы компоненту.

но вы пишете что store !== state

Да, это так. Стор содержит в себе состояние и методы для работы с ним.

путаница с тем, что должно возвращаться из этой функции.

из этой функции должен возвращаться объект, данные из которого будут смёржены с пропсами того компонента, который передаётся в connect:

const mapStateToProps = (state) => {
  // тут можно делать любые вычисления на основе стейта
  // вы можете взять нужный кусок стейта, можете создать новые данные
  // на основании тех, которые есть в стейте
  // можете вообще не брать ничего из стейта, но в этом нет смысла

  return {
    // главное - вернуть объект. Каждое поле верхнего уровня этого объекта
    // будет передано в виде пропса в компонент
  };
};

Ключевой момент - connect возвращает новый компонент, созданный на основе существующего. Этот новый компонент имеет те же пропсы плюс может иметь дополнительные (которые как раз создаются в mapStateToProps и mapDispatchToProps), а также он подписан на изменения стора.

1

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
22 сентября 8 месяцев
Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
22 сентября 8 месяцев
Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
22 сентября 8 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
22 сентября 8 месяцев
Иконка программы Верстальщик
Профессия
Вёрстка с использованием последних стандартов CSS
в любое время 5 месяцев
Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
22 сентября 10 месяцев
Иконка программы Разработчик на Ruby on Rails
Профессия
Новый
Создает веб-приложения со скоростью света
22 сентября 5 месяцев

Похожие вопросы

Аркадий Флитман 12 сентября 2021 →

В учительском решении непонятен вот этот момент: const handleRemoveTask = (id) => () => { dispatch(re...

Kostya Pershin 02 августа 2021 →

Добрый день. Могли бы подсказать, с чего лучше начинать в таких заданиях? Возникает путаница, так как все ф...

Сергей Ушаков 20 января 2021 →

Добрый день. Столкнулся с проблемой, которую не могу понять, в веб версии всё работает корректно. Пробовал ...

K R 12 января 2021 →

Добрый вечер, а почему компонент TasksBox находится не в отдельном файле (например, tasksBox.jsx) а вместе ...

Роман Емперор 20 декабря 2020 →

Я решил пробежаться по пройденному материалу и обнаружил, что моего решения упражнения нет. Не велика потер...