javascript GHD React初始组件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript GHD React初始组件相关的知识,希望对你有一定的参考价值。

@import "../core/fonts";
@import "../core/colors";
@import "../core/mixins";

.dropdown-label {
  font: 12px $helvetica-light;
  text-transform: none;
  padding-right: 15px;

  @include breakpoint(xp) {
    display: inline;
    font: 14px $helvetica-light;
  }
}

.dropdown-list {
  margin: 0;
  width: 100%;

  @include breakpoint(xp) {
    width: 300px;
  }

  * {
    list-style: none;
  }

  &__item {
    position: relative;
    padding: 30px 20px 10px 0;
    font: 12px $avantgarde-gothic;
    text-transform: uppercase;
    cursor: pointer;
    z-index: 1;
    background-color: $white;
    border-top: 1px solid $white-dark;
    text-align: center;

    @include breakpoint(sm) {
      text-align: right;
    }

    @include breakpoint(xp) {
      border-right: 1px solid $white-dark;
      padding: 20px 20px 20px 0;
      font: 14px $avantgarde-gothic;
    }

    &:first-child {
      border-top: none;
    }

    &:last-child {
      border-bottom: 1px solid $white-dark;
    }

    & > .dropdown-list {
      position: absolute;
      margin: 10px 0;

      @include breakpoint(xp) {
        margin: 20px 0;
      }

      & > .dropdown-list__item {
        padding: 20px;
        border-right: none;

        &:hover {
          background-color: $white-dark;
        }
      }
    }

    &--selected {
      background-color: $white-dark;
    }
  }

  &__item-header {
    white-space: nowrap;
  }

  .dropdown-arrow {
    margin-left: 10px;
    font-size: 15px;
    font-weight: bold;
  }
}
import React from 'react';

export const TOGGLE = 'TOGGLE';
export const CLOSE_ALL = 'CLOSE_ALL';

class Dropdown extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isOpen: false,
            selected: props.items.find(item => item.selected)
        }
    }

    componentWillMount() {
        this.props.onInit(this);
        document.addEventListener('click', e => {
            if (!e.target.closest('.dropdown-list')) {
                this.props.onTransition(CLOSE_ALL)
            }
        });
    }

    close = () => this.setState(() => ({isOpen: false}));
    toggle = () => this.setState(prevState => ({isOpen: !prevState.isOpen}));

    handleTransition = () => {
        this.props.onTransition(CLOSE_ALL, this);
        this.props.onTransition(TOGGLE, this);
        window.onkeydown = !this.state.isOpen ? e => e.preventDefault() : null;
    };

    handleSwitch = e => {
        const {items, label} = this.props;
        const index = this.props.items.indexOf(this.state.selected);
        let selected;

        switch (e.which) {
            // Enter or space bar
            case 13:
            case 32:
                this.props.onSubmit(this.props.label);
                break;

            // Up arrow
            case 38:
                selected = items[index - 1 < 0 ? items.length - 1 : index - 1];
                this.setState(() => ({selected}));
                this.props.onChange({selected, label});
                break;

            // Down arrow
            case 40:
                selected = items[index + 1 > items.length - 1 ? 0 : index + 1];
                this.setState(() => ({selected}));
                this.props.onChange({selected, label});
                break;

            // Any other non matching keys
            default:
                this.props.onTransition(CLOSE_ALL);
                window.onkeydown = null;
        }
    };

    handleClick = (selected) => {
        const {label, onChange, onSubmit} = this.props;

        this.setState(() => ({selected}));
        onChange({selected, label});
        onSubmit(label);
    };

    render() {
        const {
            listClass = '',
            listItemClass = '',
            listItemHeaderClass = '',
            iconClass = ''
        } = this.props;

        return this.props.items.length > 0 && (
            <ul
                className={`dropdown-list ${listClass}`}
                tabIndex={this.props.tabIndex}
                onKeyDown={this.handleSwitch}
            >
                <li className={`dropdown-list__item ${listItemClass}`} onClick={this.handleTransition}>
                    <span className="dropdown-label">
                        {this.props.label}
                    </span>

                    <span className={`dropdown-list__item-header ${listItemHeaderClass}`}>
                        {this.props.selected.text}
                    </span>

                    <span className={`icon-chevron-down dropdown-arrow ${iconClass}`}
                    />

                    <ul className={`dropdown-list ${this.state.isOpen ? 'visible' : 'hidden'}`}>
                        {this.props.items.map(item => (
                            <li
                                key={item.value}
                                className={`dropdown-list__item ${item.selected ? 'dropdown-list__item--selected' : ''}`}
                                onClick={() => this.handleClick(item)}
                            >
                                {item.text}
                            </li>
                        ))}
                    </ul>
                </li>
            </ul>
        );
    }
}

export default Dropdown;
import React from 'react';
import Dropdown, {CLOSE_ALL, TOGGLE} from '../Core/Dropdown';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            sortOptions: {
                label: '',
                items: []
            },
            subCategories: {
                label: '',
                items: []
            },
            dropdownList: []
        };
    }

    com = {
        sortLabel: document.querySelector('.sort-label'),
        sortOptions: document.getElementById('sort'),
        selectedSortOption: document.querySelector('#sort > option[selected]'),
        subCategoriesLabel: document.querySelector('.subcategories-label'),
        subCategories: document.getElementById('subcategories'),
        selectedSubCategory: document.querySelector('#subcategories > option[selected]')
    };

    componentWillMount() {
        let {
            sortLabel,
            sortOptions,
            selectedSortOption,
            subCategoriesLabel,
            subCategories,
            selectedSubCategory
        } = this.com;

        sortLabel = sortLabel && sortLabel.innerText || '';
        sortOptions = Array
            .prototype
            .slice
            .call(sortOptions || [])
            .map(({value, innerText, selected}) => ({
                value,
                text: innerText,
                selected
            }));

        subCategoriesLabel = subCategoriesLabel && subCategoriesLabel.innerText || '';
        subCategories = Array
            .prototype
            .slice
            .call(subCategories || [])
            .map(({value, innerText, selected}) => ({
                value,
                text: innerText,
                selected
            }));

        this.setState(() => ({
            sortOptions: {
                label: sortLabel.trim(),
                items: sortOptions,
                selected: {
                    value: selectedSortOption.value,
                    text: selectedSortOption.innerText,
                    selected: selectedSortOption.selected,
                }
            },
            subCategories: {
                label: subCategoriesLabel.trim(),
                items: subCategories,
                selected: {
                    value: selectedSubCategory.value,
                    text: selectedSubCategory.innerText,
                    selected: selectedSubCategory.selected,
                }
            }
        }));
    }

    onInit = (dropdown) => {
        this.setState(prevState => ({
            dropdownList: prevState.dropdownList.concat(dropdown)
        }));
    };

    onChange = ({selected, label}) => {
        let items = [];
        const unselect = option => {
            option.selected = false;
            return option;
        };

        switch (label.toLowerCase()) {
            case 'sort by':
                items = this.state.sortOptions.items.map(unselect);
                break;
            case 'shop by':
                items = this.state.subCategories.items.map(unselect);
                break;
        }

        const index = items.indexOf(selected);
        items[index].selected = true;
    };

    onTransition = (ACTION, dropdown) => {
        switch (ACTION) {
            case TOGGLE:
                dropdown.toggle();
                break;
            case CLOSE_ALL:
                this.state.dropdownList.forEach(dropdownItem => {
                    if (!dropdown || dropdownItem !== dropdown) {
                        dropdownItem.close();
                    }
                });
                break;
        }
    };

    onSubmit = (label) => {
        let selectedItem;
        let selectBox;
        const form = document.getElementById('refineForm');

        switch (label.toLowerCase()) {
            case 'sort by':
                selectedItem = this.state.sortOptions.items.find(item => item.selected);
                selectBox = document.getElementById('sort');
                break;
            case 'shop by':
                selectedItem = this.state.subCategories.items.find(item => item.selected);
                selectBox = document.getElementById('subcategories');
                break;
        }

        const option = Array
            .from(selectBox.children)
            .map(option => {
                option.removeAttribute('selected');
                return option
            })
            .find(option => option.value === selectedItem.value);

        option.setAttribute('selected', true);
        form.submit();
    };

    render() {
        return (
            <div className="product-menu">
                <div className="product-menu__wrapper">
                    <Dropdown
                        label={this.state.subCategories.label}
                        items={this.state.subCategories.items}
                        selected={this.state.subCategories.selected}
                        tabIndex={0}
                        onInit={this.onInit}
                        onSubmit={this.onSubmit}
                        onChange={this.onChange}
                        onTransition={this.onTransition}
                    />

                    <Dropdown
                        label={this.state.sortOptions.label}
                        items={this.state.sortOptions.items}
                        selected={this.state.sortOptions.selected}
                        tabIndex={1}
                        onInit={this.onInit}
                        onSubmit={this.onSubmit}
                        onChange={this.onChange}
                        onTransition={this.onTransition}
                    />
                </div>
            </div>
        );
    }
}

export default App;
<%@ taglib prefix="dropdown" tagdir="/WEB-INF/tags/refresh-dropdown" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>

<%@ attribute name="category" required="true" type="com.ghdhair.app.data.CategoryData" %>

<form
        action="<c:url value="${requestScope['javax.servlet.forward.request_uri']}"/>"
        id="refineForm"
        name="refineForm"
        method="post"
        class="hidden"
>
    <c:if test="${!empty category.categories}">
        <s:message code="category.select.label" var="shopLabel"/>
        <dropdown:menu
                label="${shopLabel}"
                items="${category.categories}"
                currentValue="${category.seoName}"
                input_name="subcategories"
                valuePropertyName="seoName"
        />
    </c:if>

    <c:if test="${!empty category.products}">
        <s:message code="category.sort.label" var="sortLabel"/>
        <dropdown:menu
                label="${sortLabel}"
                items="${sortOptions}"
                currentValue="${sortOption}"
                input_name="sort"
        />
    </c:if>
</form>

<div id="refresh-product-menu-app">
</div>
import React from 'react';
import ReactDOM from 'react-dom';

const appContainer = document.getElementById('refresh-product-menu-app');
if (appContainer) {
    (async () => {
        const {default: App} = await import ('./App');
        ReactDOM.render(<App/>, appContainer);
    })();
}

以上是关于javascript GHD React初始组件的主要内容,如果未能解决你的问题,请参考以下文章

Reactreact概述组件事件

react-datepicker 没有初始值

react验证码刷新闪烁

无法访问 JavaScript 对象数组 (React.js) 中的属性

React 组件没有得到 reducer 设置的 redux 初始状态

React:告诉子组件“重新初始化”,即使传递的道具相同