Задача
Фигурные скобки в JSX ({}
) ограничены по функциональности, поскольку они поддерживают только одиночное выражение . Думайте о выражении как о блоке кода, который интерпретатор / компилятор будет оценивать как одну строку кода. Объединение такой сложной логики в одном выражении сложно реализовать и прочитать.
Решение
Используйте выражения JSX в сочетании с другими полезными функциями React / Javascript. Приведенное ниже решение написано на ES6 (дайте мне знать, если вам нужно перенести его на ES5).
Импорт Icon
из соответствующего файла или определение его в этом файле. Вы можете заполнить остальные ваши компоненты в функции render
.
Логика разбита на функции, облегчающие понимание того, чего пытается достичь код. Проверьте это и посмотрите, работает ли он для вас.
Ниже также есть примечания, объясняющие некоторые фрагменты.
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import Icon from '...<icon directory>...';
class IconExample extends Component {
constructor(props) {
super(props);
this.getIconInfo = this.getIconInfo.bind(this);
this.getIcons = this.getIcons.bind(this);
}
getIcons(driveFiles) {
return driveFiles.map((driveFileKey, i) => {
const dotIndex = driveFileKey.name.lastIndexOf('.') + 1;
const driveFormat = driveFileKey.name.substr(dotIndex);
console.log('filename---> %s', driveFormat);
const iconInfo = this.getIconInfo(driveFormat);
if (iconInfo === null) {
return null;
}
return (
<div key={`${driveFormat}${i}`}>
<Icon icon={iconInfo} />
</div>
);
});
}
getIconInfo(fileExtension) {
const iconInfo = ['fal'];
if (fileExtension === 'pdf') {
iconInfo.push('file-pdf');
return iconInfo;
} else if (fileExtension === 'doc') {
iconInfo.push('file-doc');
return iconInfo;
} else if (fileExtension === 'jpg') {
iconInfo.push('file-jpg');
return iconInfo;
}
return null;
}
render() {
return (
<Fragment>
{this.props.driveFiles.length > 0 &&
this.getIcons(this.props.driveFiles)
}
</Fragment>
);
}
}
IconExample.propTypes = {
driveFiles: PropTypes.array,
};
export default IconExample;
Примечания * * 1023
Выражение Оценка
{this.state.driveFiles.length > 0 &&
this.getIcons(this.state.driveFiles)
}
Оператор &&
(and) оценивает операторы с обеих сторон и возвращает оператор last , тот, что справа. Таким образом, this.getIcons(this.props.driveFiles)
будет оцениваться только в том случае, если this.state.driveFiles.length > 0
вернет true.
Ключи
<div key={${driveFormat}${i}}>
<Icon icon={iconInfo} />
</div>
В этой части документов React объясняется, почему мы используем ключи при возврате из итераторов.
Связывание в конструкторе
this.getIconInfo = this.getIconInfo.bind(this);
this.getIcons = this.getIcons.bind(this);
Эта проблема связана с использованием «классических» функций javascript, но я верю в самый современный ECMAScript и выше, вы можете использовать функции стрелок в определениях классов, чтобы устранить необходимость. Мы обязуемся гарантировать, что this
будет ссылаться в функции, и мы хотим, чтобы это был компонент, который мы используем, а не глобальный this
или какой-либо другой параметр по умолчанию в этом случае.