<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>@0xldev</title><subtitle>24 y.o, frontend developer from Russia</subtitle><author><name>@0xldev</name></author><id>https://teletype.in/atom/0xldev</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/0xldev?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@0xldev?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=0xldev"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/0xldev?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-17T10:22:59.326Z</updated><entry><id>0xldev:n5dIne3EYx0</id><link rel="alternate" type="text/html" href="https://teletype.in/@0xldev/n5dIne3EYx0?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=0xldev"></link><title>Особенности условного рендеринга в React</title><published>2022-01-21T05:33:21.294Z</published><updated>2022-01-21T05:51:14.039Z</updated><summary type="html">Что здесь: передаем пропом число id, и если оно есть, то рендерим элемент списка. </summary><content type="html">
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;0zWP&quot; data-lang=&quot;javascript&quot;&gt;const Header: FC&amp;lt;{ id: number }&amp;gt; = ({ id }) =&amp;gt; (
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;lt;/a&amp;gt;Главная&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contacts&amp;quot;&amp;lt;/a&amp;gt;Контакты&amp;lt;/li&amp;gt;

    {id &amp;amp;&amp;amp; (
      &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/somewhere&amp;quot;&amp;gt;куда-то&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    )}
  &amp;lt;/ul&amp;gt;
);&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;lgxs&quot;&gt;Что здесь: передаем пропом число id, и если оно есть, то рендерим элемент списка. &lt;/p&gt;
  &lt;p id=&quot;dB8r&quot;&gt;&lt;br /&gt;Вроде бы все хорошо, но на самом деле опасно. Если id будет равен нулю, то компонент не отрендерится. Зато отрендерится 0.&lt;/p&gt;
  &lt;p id=&quot;n2pZ&quot;&gt;То есть при &lt;code&gt;id === 0&lt;/code&gt;на странице получится такая разметка&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;Wgy8&quot; data-lang=&quot;javascript&quot;&gt;&amp;lt;ul&amp;gt;
 &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;lt;/a&amp;gt;Главная&amp;lt;/li&amp;gt;
 &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contacts&amp;quot;&amp;lt;/a&amp;gt;Контакты&amp;lt;/li&amp;gt;&amp;gt;
  0
&amp;lt;/ul&amp;gt;&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;UuuS&quot;&gt;&lt;strong&gt;Почему так&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;8k1I&quot;&gt;Первый момент, что если при логическом операторе И (&amp;amp;&amp;amp;) один из операторов ложен, то он и вернется. То есть в нашем случае вернулся 0, т.к. число ноль при логическом преобразовании ложно.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;vpGC&quot; data-lang=&quot;javascript&quot;&gt;0 &amp;amp;&amp;amp; 1 // 0
2 &amp;amp;&amp;amp; 3 // 3
1 &amp;amp;&amp;amp; 0 &amp;amp;&amp;amp; 2 // 0&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;O56y&quot;&gt;Второй момент, что в реакте рендерятся числа. То есть вы можете сделать компонент, который возвращает число 0 и все нормально отобразится.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;z207&quot; data-lang=&quot;javascript&quot;&gt;export const App = () =&amp;gt; {
 return 0;
}&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;1Lta&quot;&gt;Другое дело, если бы вернулся не 0, а false — его реакт не отрендерит.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;6d50&quot; data-lang=&quot;javascript&quot;&gt;export const App = () =&amp;gt; {
 return false;
}&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;TUEH&quot;&gt;Поэтому если хоть один логический оператор не булево значение, то я всегда оборачиваю аргументы в Boolean.&lt;/p&gt;
  &lt;p id=&quot;RU3X&quot;&gt;То есть в нашем случае лучше будет&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;SWZo&quot; data-lang=&quot;javascript&quot;&gt;const Header: FC&amp;lt;{ id: number }&amp;gt; = ({ id }) =&amp;gt; (
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;lt;/a&amp;gt;Главная&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contacts&amp;quot;&amp;lt;/a&amp;gt;Контакты&amp;lt;/li&amp;gt;

    {Boolean(id) &amp;amp;&amp;amp; (
      &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/somewhere&amp;quot;&amp;gt;куда-то&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    )}
  &amp;lt;/ul&amp;gt;
);&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;jlQK&quot;&gt;Альтернативная запись&lt;/p&gt;
  &lt;p id=&quot;fkJk&quot;&gt;В логическом контексте, можно также преобразовать двойным отрицанием: !!&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;d736&quot; data-lang=&quot;javascript&quot;&gt;const Header: FC&amp;lt;{ id: number }&amp;gt; = ({ id }) =&amp;gt; (
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;lt;/a&amp;gt;Главная&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contacts&amp;quot;&amp;lt;/a&amp;gt;Контакты&amp;lt;/li&amp;gt;

    {!!id &amp;amp;&amp;amp; (
      &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/somewhere&amp;quot;&amp;gt;куда-то&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    )}
  &amp;lt;/ul&amp;gt;
);&lt;/pre&gt;
  &lt;/section&gt;

</content></entry><entry><id>0xldev:Redux</id><link rel="alternate" type="text/html" href="https://teletype.in/@0xldev/Redux?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=0xldev"></link><title>Redux — для чего он нужен</title><published>2021-04-10T17:58:34.255Z</published><updated>2022-01-21T05:48:28.348Z</updated><summary type="html">&lt;img src=&quot;https://teletype.in/files/bb/7b/bb7b0f16-52c5-4562-9bed-19b33de89be4.jpeg&quot;&gt;Все взаимодействие нашего приложения происходит в интерфейсе. Но хочется отделить бизнес-логику, чтобы было проще разрабатывать и дебажить.</summary><content type="html">
  &lt;p id=&quot;MFle&quot;&gt;Все взаимодействие нашего приложения происходит в интерфейсе. Но хочется отделить бизнес-логику, чтобы было проще разрабатывать и дебажить.&lt;/p&gt;
  &lt;figure id=&quot;0tTJ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/bb/7b/bb7b0f16-52c5-4562-9bed-19b33de89be4.jpeg&quot; width=&quot;879&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HT13&quot;&gt;Одна из архитектур для работы с данными Flux. Мы делаем действие из интерфейса, в действии читаем логику и обновляем состояние. А интерфейс всегда отображает текущее состояние.&lt;/p&gt;
  &lt;figure id=&quot;yUEZ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/9d/fd/9dfdb5e4-fa5e-4103-ab55-2ae77c186410.jpeg&quot; width=&quot;879&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ybJx&quot;&gt;Вот названия по-научному.&lt;/p&gt;
  &lt;figure id=&quot;tJcZ&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/91/27/9127d0d5-5d55-4983-9f0c-0b0da6abc1d9.jpeg&quot; width=&quot;879&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qSws&quot;&gt;И картинка из интернета&lt;/p&gt;
  &lt;figure id=&quot;tWUc&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/9a/57/9a577efb-caf2-4229-bcb8-56f84cb7b099.png&quot; width=&quot;570&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IzVn&quot;&gt;Redux — это реализация архитектуры Flux.&lt;/p&gt;
  &lt;p id=&quot;KT7m&quot;&gt;Мы создаем store с помощью функции createStore&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;UVo6&quot;&gt;const store = createStore(reducer, middlewares);
&lt;/pre&gt;
  &lt;p id=&quot;ah9k&quot;&gt;&lt;strong&gt;reducer&lt;/strong&gt; — это функция, которая обновляет стор в зависимости от экшена.&lt;/p&gt;
  &lt;p id=&quot;TQMy&quot;&gt;&lt;strong&gt;middlewares&lt;/strong&gt; — это промежуточные слои, прежде чем экшн дойдет до редьюсера.&lt;/p&gt;
  &lt;p id=&quot;LeMj&quot;&gt;Дальше стор можно диспатчить и смотреть текущее состояние&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;p9PW&quot;&gt;// В диспатч обязательно надо передать type, тип экшена,
// чтобы редьюсер мог обновить состояние по этому типу
// payload — это дополнительные данные
store.dispatch({ type: &amp;#x27;myAction&amp;#x27;, payload: { s: 2 } });&lt;/pre&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;emZv&quot;&gt;store.getState(); // Вернет текущее состояние
&lt;/pre&gt;
  &lt;p id=&quot;qTSW&quot;&gt;В редьюсере важно всегда возвращать новый объект, чтобы не было неочевидных багов, т.к. интерфейс отображает текущее состояние. После того, как новое состояние вернется из редьюсера, реакт обновится.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;v4bf&quot;&gt;const reducer = (state = {}, { type, payload }) =&amp;gt; {
  switch (type) {
    case &amp;#x27;myAction&amp;#x27;: {
      return {
        ...state,
        result: 2 + payload.s,
      };
    }
 
    default: {
      return state;
    }
  }
};&lt;/pre&gt;
  &lt;p id=&quot;grY1&quot;&gt;Редакс подключается к реакту также, как мы подключаем контекст&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;jmQ9&quot;&gt;import { Provider } from &amp;#x27;react-redux&amp;#x27;;
import { createStore } from &amp;#x27;redux&amp;#x27;;
 
const store = createStore(() =&amp;gt; ({}));
 
const App = () =&amp;gt; (
  &amp;lt;Provider store={store}&amp;gt;
    &amp;lt;h1&amp;gt;Привет, это 0xLDev&amp;lt;/h1&amp;gt;
  &amp;lt;/Provider&amp;gt;
);
&lt;/pre&gt;
  &lt;p id=&quot;fxiB&quot;&gt;Чтобы использовать состояние или диспатчить экшены, используем хуки&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;Orxa&quot;&gt;import { useDispatch, useSelector } from &amp;#x27;redux&amp;#x27;;
import { getFunc } from &amp;#x27;./actions&amp;#x27;;
 
const Component = () =&amp;gt; {
  const dispatch = useDispatch();
  const name = useSelector((state) =&amp;gt; state.name);
 
  return (
    &amp;lt;button onClick={() =&amp;gt; dispatch(getFunc)}&amp;gt;{name}, нажми на меня!&amp;lt;/button&amp;gt;
  );
};&lt;/pre&gt;
  &lt;p id=&quot;Kzca&quot;&gt;Для асинхронных запросов в экшенах используем библиотеку redux-thunk. Она позволяет не возвращать объект из экшена сразу, а задиспатчить его отдельно. Причем несколько раз.&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;0g9D&quot;&gt;export const getFunc = () =&amp;gt; (dispatch, getState) =&amp;gt; {
  const state = getState();  // Посмотреть состояние для валидации, например. 
  dispatch({ type: &amp;#x27;fetchStart&amp;#x27; });
  fetch(url)
    .then(() =&amp;gt; dispatch({ type: &amp;#x27;fetchSuccess&amp;#x27; }))
    .catch(() =&amp;gt; dispatch({ type: &amp;#x27;fetchFail&amp;#x27; }))
};&lt;/pre&gt;
  &lt;p id=&quot;SlFW&quot;&gt;redux-thunk работает через middleware. Подключаем к стору так&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;K4qk&quot;&gt;import { createStore, applyMiddleware } from &amp;#x27;redux&amp;#x27;;
import thunk from &amp;#x27;redux-thunk&amp;#x27;;
 
const store = createStore(reducer, applyMiddleware(thunk));&lt;/pre&gt;
  &lt;p id=&quot;kKBm&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;LKvq&quot;&gt;MiddleWare — это функция, которая вызовется перед попаданием в редьюсер. Мы пишем свои middleware для логирования. Внутри он выглядит так&lt;/p&gt;
  &lt;pre data-lang=&quot;javascript&quot; id=&quot;Y0XP&quot;&gt;const middleware = (store) =&amp;gt; (next) =&amp;gt; (action) =&amp;gt; {
  // ...тут делаем все, что нам нужно
  
  // когда будем готовы передать экшн дальше
  // в редьюсер или следующий по порядку миддлвэр
  // пишем так. Вызвать можно только один раз
  next(action);
};&lt;/pre&gt;
  &lt;p id=&quot;9Fv9&quot;&gt;Самый кайф редакса в логировании бизнес-логики. И redux-devtools-extension помогает удобно смотреть изменения.&lt;/p&gt;

</content></entry></feed>