2015-02-02 1 views
3

Я столкнулся с решением о том, как составлять мои компоненты, и мне интересно, есть ли у сообщества какие-либо идеи о том, что является лучшей практикой.Лучшая практика: инкапсулировать компоненты или сочинять глубоко, используя props.children

1: Инкапсулировать компоненты, чтобы скрыть детали.

Владелец делает:

<List ... /> 

Список предоставляет:

<Item ... /> 

Item оказывает:

<div>...</div> 

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

2: компоненты гнездо глубоко в верхней, сохраняющие состояние вид-контроллеры

Владелец штукатурок:

<List> 
    <Item> 
    <div>...</div> 
    </Item> 
</List> 

В этой версии, владелец знает все о составе его дети, но сами компоненты не очень полезны, потому что они ничего не знают о домене. Однако они более многоразовые.

3: инкапсулируют общие компоненты в области специфических компонентов

Это гибрид варианта 1 и вариант 2

Владелец делает:

<DomainList ... /> 

DomainList оказывает:

<List ...> 
    <DomainItem .../> 
</List> 

Домен Предметы искусства:

<Item ...> 
    ... 
</Item> 

Владелец ничего не знает об общем списке, DomainItem или общем товаре.

Какой подход лучше? Кто-нибудь имел успех или неудачу с любым из этих подходов? Что случилось?

ответ

2

Компоненты не менее многоразовые, потому что они диктуют большинство вещей о том, как они должны быть визуализированы. Вы даже можете утверждать, что они более многократно используются, поскольку компонент, использующий его, не должен знать ничего о том, как это проявляется.

Очень легко попасть в паралич по состоянию анализа, когда вы начинаете думать об этих вещах. Мой подход к созданию компонентов React:

  1. Старайтесь не иметь состояния в компоненте и не передавать его в виде реквизита, а не вверху в иерархии.
  2. Используйте только this.props.children для компонентов оболочки, которые не знают о том, что в него входит. Общий материал, такой как всплывающее окно, вкладка и т. Д.
  3. Не начинайте извлекать материал в другие компоненты, потому что «я могу повторно использовать это в другом месте позже». Вместо этого я извлекаю только один раз, когда знаю, что мне это нужно в другом месте.
  4. Вместо того, чтобы думать, как автор этого компонента, я стараюсь думать, как пользователь компонента. Задайте себе такие вопросы, как «Как мне передать данные этому компоненту?», «Необходимо ли уведомлять пользователя об этом компоненте, когда что-то меняется в нем?», «Какую гибкость мне нужно при использовании этого компонента?» , Легко далеко ходить сюда с обобщением, поэтому я также стараюсь не слишком абстрагироваться.

Я имею тенденцию видеть два разных типа компонентов. Материал общего назначения, который является либо настолько общим, что я мог бы повторно использовать их между проектами или конкретными приложениями, но достаточно общий, что я буду использовать их много в разных частях приложения для разных целей. Тогда есть конкретные компоненты, которые имеют очень специфические цели, такие вещи, как «отобразить этот список дел» или «визуализировать эту форму для редактирования todo». Они, как правило, используют компоненты общего назначения, но определенно не наоборот.

Обычно я хорошо знаю, когда начинаю создавать компонент, который из этих типов будет. И для компонентов общего назначения я стараюсь сделать их максимально гибкими и открытыми. Для конкретных целей я делаю их больше похожими на черные ящики, вроде «Просто дайте мне данные, и я возьму его оттуда». Поскольку они имеют очень описательные имена и знают все, что нужно знать о том, как сделать себя, легко понять, что происходит при чтении кода, который их использует.

В вашем примере, я бы сказал, что компонент является компонентом общего назначения, и я определенно хочу сделать его гибким. Я бы, наверное, конкретный компонент для списка, я в здании, а также, что-то вроде TodoList, которые могли бы выглядеть примерно так:

var TodoList = React.createClass({ 
    render() { 
    return (
     <List> 
     {this.props.todos.map(todo => <ListItem>{todo.text}</ListItem>)} 
     </List> 
    ); 
    } 
}); 

Другим вариантом было бы что-то вроде этого:

var ListItem = React.createClass({ 
    render() { 
    return <li>{this.props.item.text}</li>; 
    } 
}); 

var TodoList = React.createClass({ 
    render() { 
    return <List items={this.state.items} listItemComponent={ListItem} />; 
    } 
}); 

В этом случае компонент List выполняет итерацию по всем элементам и использует переданный компонент listItemComponent для визуализации элементов.

TL; DR

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