Комментарии 17
О как! Недавно столкнулся с подобной проблемой и пришлось писать свой велосипед. Но оказывается уже есть более лаконичное решение. Спасибо!
<Todo key={todo.id} todo={todo} onClick={onTodoClick} />
Так не произойдет никакого перерендеринга.
Вообще вещать побольше connectов исключительно для контроля над распространением изменений — интересная практика.
Connect — начало любого изменения, потому что дергается непосредственно стором как бы глубоко он не сидел
Connect — конец любого изменения, потому что SCU не пропустит никакие нежданные изменения прилетевшие сверху.
Подробнее можно вот тут почитать -> medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97
По другому идею не продать.
Отличное решение, должно сильно упростить составные состояния.
По поводу статьи: не оставляйте необъявленных переменных в примерах, излазился в поисках onTodoClick
.
Чисто для сравнения компонент TreeView на основе данных из плоского массива на SvelteJS:
<ul>
{{#each leafs as leaf}}
<li id="leaf{{leaf.id}}">
<h6>{{leaf.title}}</h6>
{{#if leaf.childs}}
<:Self leafs="{{childs(leaf.childs)}}" />
{{/if}}
</li>
{{/each}}
</ul>
<script>
import tree from './tree.js'
export default {
data: () => ({
leafs: []
}),
helpers: {
childs: childs => tree.apply(null, childs)
}
};
</script>
Вот живой пример поиграться. Можно выставлять любые начальные id-шники дерева в json-объекте справа.
На полном серьезе не понимаю, почему столь простая задача должна решаться так сложно. Конструктивная критика приветствуется.
Создаётся стойкое ощущение что вы себя мучаете только бы чтоб использовать React. Раз с React так много проблем, то может использовать другие решения?
статьи про React почему-то делятся на 2 вида: 1) как красно что мы выбрали React, вот какой классный “Hello World”; 2) решаем проблемы React.
«Есть всего два типа языков программирования: те, на которые люди всё время ругаются, и те, которые никто не использует.» Бьёрн, Страуструп
А чем хуже с точки зрения производительности:
const TodoList = ({todos}) => (
<ol>
{todos.map( item => <ConnectedTodo key={item.id} item={item} />)}
</ol>
);
чем предложенный вариант по ID?
const TodoList = ({todos}) => (
<ol>
{todos.map( id => <ConnectedTodo key={id} id={id} />)}
</ol>
);
Во варианте с item
мы же так же можем не рендерить если нет изменений (при условии иммутабельности item).
Если же добавить memoize-state из моей другой статьи, но «контейнер» будет регировать только на изменение колличества todo или ID, полностью игнорируя данные внутри todo элементов, что уже может быть интересно в некоторых случаях.
Еще один плюс — данный подход позволяет «разорвать» связь стейта, его использования и редьюсера.
Сейчас редьюсер и селектор в неком смысле «симметричны», возможность модифицировать стейт под нужды клиента позволяет это ограничение(это — ограничение) разорвать.
Да, но зато так мы б могли обойтись только массивом todo и никаких индексов из ID не надо. Имхо, идея с ID здравая и элегантная, но это тот случай, когда с водой ребенка выплеснули. Лучше какой-то средний вариант взять, т.е. не спредать item в компонент, но и не закручивать гайки по максимуму с селектором по ID в connect. А чтоб работало совсем по красоте можно еще и обернуть в onlyUpdateForKeys из recompose, чтоб заигнорить лишнее.
Restate — или как превратить бревно Redux в дерево