Я пытаюсь создать компонент без сохранения состояния в React с единственной целью - использовать его как оболочку многократного использования. Я также использую модули CSS, потому что я хочу иметь полностью модульный CSS.

Дело в том, что я не хочу добавлять ненужные элементы (и тем более <div>), но вместо этого я хочу использовать фрагменты React.

Теперь проблема, которую я имею, является фрагментом (по крайней мере пока), не принимают classNames. Так что, если я попробую это:

// В Wrapper.js:

import React, { Fragment } from 'react'
import styles from './Wrapper.css'

const wrapper = (props) => (
    <Fragment className={styles.wrapper}>
        {props.children}
    </Fragment>
)

export default wrapper

В (например) Navbar.js:

import React from 'react'
import styles from './Navbar.css'
import Wrapper from '../../Layout/Wrapper'

const navBar = (props) => (
    <nav className={styles.navBar}>
        <Wrapper>
            This is the site's main navigation bar.
        </Wrapper>
    </nav>
)

export default navBar

Теперь я могу, конечно, использовать div вместо Fragment, но есть ли другой обходной путь, чтобы избежать использования ненужной разметки, о которой я совершенно не знаю в этот час ночи? :)

Заранее благодарим за понимание, рекомендацию, исправление или любую другую помощь!

22
NTP 2 Мар 2018 в 16:06

4 ответа

Лучший ответ

Фрагменты позволяют группировать список детей без добавления дополнительных узлов в DOM. - https://reactjs.org/docs/fragments.html

То, что фрагменты пытаются решить, это ненужные элементы dom, но это не значит, что фрагменты полностью заменят div. Если вам нужно добавить className туда, ясно, что либо вы добавляете элемент dom в этом случае другой div, либо добавляете класс к его родителю.

21
John Baker 2 Мар 2018 в 13:29

Использование Fragment означает отсутствие добавления дополнительного узла в DOM.

Если вы хотите присвоить className узлу, вам придется использовать div.

2
Amanshu Kataria 2 Мар 2018 в 13:45
  1. Создайте файл CSS и импортируйте его в свой App.js
  2. Создайте компонент более высокого порядка с помощью Class.js, как показано ниже
    import React from  'react';
    
    const withClass = (WrappedComponent, className) => {
        return props => (
            <div className={className}>
                <WrappedComponent {...props} />
            </div>
        );
    };
    
    export default withClass;
  1. Импортируйте свою информацию тоже.
  2. В вашем App.js напишите что-то вроде ниже
    <React.Fragment>
        <p>Some JSX code here</p>
    <React.Fragment>
    
    export default withClass(App, classes.App);

Я создал класс .App внутри моего css-файла и импортировал его, чтобы позже использовать его с classes.App. Таким образом, вы можете применить любой класс css, который вы создаете внутри вашего css. Вы можете использовать один и тот же wrapperComponent для упаковки каждого имеющегося компонента, просто импортировав его и изменив экспорт в своем компоненте. Вам просто нужно сделать имя класса по вашему выбору и использовать его в операторе экспорта вашего компонента. Когда вы пишете реквизит с оператором распространения (...). Все реквизиты из вашего компонента будут переданы этому оберточному компоненту.

PS: английский не мой родной язык, поэтому я не очень хорошо объясняю, но этот код поможет. Буду признателен модератору, взглянув на мое объяснение.

0
Atul Chavan 24 Дек 2019 в 13:37

Таким образом, единственное, что делает Wrapper / Fragment, это действует как оболочка CSS над потомками nav?

Я не очень разбираюсь в css-модулях, но если бы я хотел избежать дополнительного узла DOM только для className, я бы использовал что-то вроде этого, чтобы применить оба classNames к <nav>:

import React from 'react'
import navStyles from './Navbar.css'
import wrapperStyles from './Wrapper.css'

const navBar = (props) => (
    <nav className={`${navStyles.navBar} ${wrapperStyles.wrapper}`}>
       This is the site's main navigation bar.
    </nav>
)

export default navBar
0
pawel 2 Мар 2018 в 13:55