2016-12-07 2 views
0

Не ссылаясь на магию props.children, но могу ли я заставить дочерний элемент иметь определенные атрибуты (или добавленные значения к атрибуту) на элементе верхнего уровня, который он создает? Пример сценарий:Могу ли я накладывать атрибуты на детей?

const Button = 
    (props) => 
    (<button type="button" id={props.id} className={['btn'].concat(props.classNames)}>{props.children}</button>); 

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

Даже лучше, если это позволит вещи, помимо дополнительных классов CSS, но это текущая цель.

Возможно ли это сделать детям без их знания?

+0

Это может помочь: https://www.amazon.com/Parenting-Dummies-Sandra-Hardin-Gookin/dp/0764554182 – jtbandes

ответ

1

Это, вероятно, что вы ищете (использования ES6 распространения оператор):

const Button = (props) => (<button {...props}>{props.children}</button>); 

Он проходит весь реквизит that've был указан на Button компонента до <button> элемента, так что в случае, если вы укажете:

<Button className="my-class" id="10">submit</Button> 

<button> элемент получит: <button className="my-class" id="10" >submit</button>

Обновление: Если вы хотите передать только некоторые реквизиты, но не все из них, вы можете рассмотреть возможность назначения объекта компоненту верхнего уровня и использовать его в качестве реквизита на дочернем.

const Button = (props) => (<button {...props.data}>{props.children}</button>) 

<Button data={{ id: 10, className: 'my-class' }}>submit</Button> 
+0

, так как я всегда видел этот пример ('{...реквизит} ') с волшебным дополнением' {props.children}, которого я никогда не использовал, я всегда думал, что это связано с детьми. Это потрясающе, если это работает так, как мне кажется, позвольте мне попробовать. – Maslow

+0

чувствует, что оператор спредов слишком переполнен, и плохой для загрузки, вы не можете использовать черный список, я держу пари, вы должны забросить все свойства, даже те, которые не должны идти к детям ребенка. Мне бы очень хотелось иметь возможность просто передавать вещи, подобные родительским атрибутам data-*. или слить «имена классов» на дочерние элементы – Maslow

+0

, если вам нужно отфильтровать некоторые реквизиты, вы можете применить фильтр к реквизитам: –

0

Вы можете клонировать каждый ребенок с помощью React.cloneElement(), который позволяет объединить в своем реквизите ...

React.Children.map(props.children, child => { 
    return React.cloneElement(child, { newProp: 1, otherProp: 'XYZ' }); 
}); 

... так, у вас может выглядеть примерно так:

const Button = (props) => { 
    const className = ['btn'].concat(props.classNames).join(' '); 

    <button type="button" id={props.id} className={className}> 
    { 
     React.Children.map(children, child => (
     React.cloneElement(child, { className }) 
    )) 
    } 
    </button> 
}; 
0

Чтобы ответить на ваш вопрос, вы можете либо использовать {...this.props}, либо использовать refs, чтобы применить класс императивно в componentDidMount/componentDidUpdate родительского класса.

Однако я бы старался не использовать любой подход. Текущая версия React предупреждает, когда неизвестные свойства заданы на узле DOM, а {...this.props} часто приводит вас туда. Императивный подход также не очень хорош, поскольку он нарушает поток функциональных данных и в основном делает использование React устаревшим.

Я бы постарался четко указать, какие функции/функции вы хотите от компонента, и строго указать их через реквизиты. Это означает также размещение className, style и других атрибутов, которые кажутся тривиальными. Часто также полезно использовать больше семантических реквизитов: например. colorScheme="confirm", size="big", type="outline" являются примерами того, что может быть полезно для компонента Button. Таким образом можно избежать повторения при использовании кнопки в нескольких местах.

Если вы расскажете мне больше о вашем конкретном прецеденте, я думаю, что может быть хорошее решение.

Смежные вопросы