<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>@0xldev</title><generator>teletype.in</generator><description><![CDATA[24 y.o, frontend developer from Russia]]></description><image><url>https://teletype.in/files/80/c1/80c14c6b-fafa-47ac-b82b-3ea873f4cde8.jpeg</url><title>@0xldev</title><link>https://teletype.in/@0xldev</link></image><link>https://teletype.in/@0xldev?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=0xldev</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/0xldev?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/0xldev?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 19 Apr 2026 11:59:57 GMT</pubDate><lastBuildDate>Sun, 19 Apr 2026 11:59:57 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@0xldev/n5dIne3EYx0</guid><link>https://teletype.in/@0xldev/n5dIne3EYx0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=0xldev</link><comments>https://teletype.in/@0xldev/n5dIne3EYx0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=0xldev#comments</comments><dc:creator>0xldev</dc:creator><title>Особенности условного рендеринга в React</title><pubDate>Fri, 21 Jan 2022 05:33:21 GMT</pubDate><description><![CDATA[Что здесь: передаем пропом число id, и если оно есть, то рендерим элемент списка. ]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <pre id="0zWP" data-lang="javascript">const Header: FC&lt;{ id: number }&gt; = ({ id }) =&gt; (
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/&quot;&lt;/a&gt;Главная&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/contacts&quot;&lt;/a&gt;Контакты&lt;/li&gt;

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

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

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

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

]]></content:encoded></item></channel></rss>