React-defaultProps против параметров ES6 по умолчанию при разрушении (проблемы с производительностью)
Я только что наткнулся на вопрос о производительности React, когда настройки значений по умолчанию в одном из моих функциональные компоненты без гражданства.
этот компонент был defaultProps
который определил row: false
, но мне это не понравилось, потому что defaultProps
и в конце файла, что на самом деле затрудняет его просмотр. Таким образом, мы не знаем свойства default. Поэтому я переместил его в объявление функции напрямую и назначил его, используя значение по умолчанию ES6 для параметров.
const FormField = ({
row = false,
...others,
}) => {
// logic...
};
но потом мы поспорили с коллегой об этом быть хорошей идеей или нет. Потому что это может показаться тривиальным, но также может оказать большое влияние на выступления с реагировать не в курсе значения по умолчанию.
Я считаю, что в этом случае это тривиально. Потому что это логическое, а не объект / массив и поэтому не будет рассматриваться как другое значение во время примирение.
но, давайте теперь посмотрим более продвинутый вариант использования:
const FormField = ({
input: { name, value, ...inputRest },
label = capitalize(name),
placeholder = label,
row = false,
meta: { touched, error, warning },
...others,
}) => {
// logic...
};
здесь, я основываю значение placeholder
С label
, который основан на input.name
. Использование ES6 destructuring со значениями по умолчанию для параметров делает все это довольно легко писать / понимать, и это работает как шарм.
а это хорошая идея? А если нет, то как вы это сделаете правильно?
2 ответов
я поговорил с несколькими людьми на канале Discord #reactiflux и фактически получил ответ, который я искал.
есть в основном три варианта использования с компонентами React, и в некоторых из них разрушение парамов повлияет на производительность, поэтому важно понять, что происходит на капоте.
функциональный компонент без состояния
const MyComponent = ({ name = 'John Doe', displayName = humanize(name), address = helper.getDefaultAddress() }) => {
return (
<div>{displayName}</div>
);
};
это функциональный компонент без состояния. Нет никакого состояния, и оно функционально, потому что оно это не Class
экземпляр, но простая функция.
в этом случае нет жизненного цикла, у вас не может быть componentWillMount
или shouldComponentUpdate
или constructor
там. И поскольку нет управления жизненным циклом,нет никакого влияния на производительность. Этот код совершенно действителен. Некоторые могут предпочесть обрабатывать значение по умолчанию displayName
значение в теле функции, но в конце концов это не имеет значения, это не повлияет на производительность.
нефункциональные без гражданства компонент
(не делайте этого!)
class MyComponent extends React.Component {
render() {
const { name = 'John Doe', displayName = humanize(name), address = helper.getDefaultAddress() } = this.props;
return (
<div>{displayName}</div>
);
}
}
это нефункциональный компонент без состояния. Нет состояния, но оно не "функционально", так как оно class
. И потому что это класс, расширяющийся React.Component
, это означает, что у вас будет жизненный цикл. Вы можете иметь componentWillMount
или shouldComponentUpdate
или constructor
там.
и, поскольку он имеет жизненный цикл, способ написания этого компонента -плохо. Но почему?
просто put, React предлагает a defaultProps
атрибут, чтобы иметь дело со значениями реквизита по умолчанию. И на самом деле лучше использовать его при работе с нефункциональными компонентами, потому что он будет вызываться всеми методами, которые полагаются на this.props
.
предыдущий фрагмент кода создает новые локальные переменные с именем name
и displayName
, а для этого применяются значения по умолчанию
глядя на расширенный вариант использования у вас есть, вы добавляете ненужные свойства к компоненту. label
и placeholder
зависят от других передаваемых свойств и, на мой взгляд, не должны указываться в качестве параметра самого компонента.
если бы я пытался использовать <FormField />
в моем приложении, и мне нужно было посмотреть, какие зависимости имеет этот конкретный компонент, я был бы немного смущен, почему вы создаете параметры, которые основаны на остальные параметры. Я бы передвинул label
и placeholder
в тело функции, так что это ясный они не являются зависимостями компонентов, а просто побочными эффектами.
что касается производительности здесь, я не уверен, что будет существенная разница в любом случае. Компоненты без состояния на самом деле не имеют "резервного экземпляра", который делают компоненты с состоянием, что означает, что нет объекта в памяти, отслеживающего компонент. Я верю, что это просто чистота. функция передачи параметров и возврата представления.
на той же ноте.. добавление PropTypes поможет с проверкой типа.
const FormField = ({
input: { name, value, ...inputRest },
row = false,
meta: { touched, error, warning },
...others,
}) => {
const label = capitalize(name),
const placeholder = label,
return (
// logic
);
};
FormField.propTypes = {
input: PropTypes.shape({
name: PropTypes.string.isRequired,
value: PropTypes.string,
}).isRequired,
meta: PropTypes.shape({
touched: PropTypes.bool.isRequired,
error: PropTypes.bool.isRequired,
warning: PropTypes.bool.isRequired,
}).isRequired,
row: PropTypes.bool.isRequired,
};