Разрушение объекта и игнорирование одного из результатов

У меня есть:

const section = cloneElement(this.props.children, {
  className: this.props.styles.section,
  ...this.props,
});

Внутри this.props у меня есть свойство styles, которое я не хочу передавать клонированному элементу.

Как я могу сделать?


person Fez Vrasta    schedule 15.06.2016    source источник
comment
Прямо сейчас я просто определяю styles: null после ...this.props, и это работает, но не очень приятно.   -  person Fez Vrasta    schedule 15.06.2016
comment
Вы пробовали мой ответ?   -  person ctrlplusb    schedule 15.06.2016
comment
Да, извините, это не работает для меня, потому что я уже определил styles ранее.   -  person Fez Vrasta    schedule 15.06.2016
comment
Итак, у вас уже есть переменная styles, объявленная выше, и ее конфликт. Я обновил свой ответ на основе этой информации.   -  person ctrlplusb    schedule 15.06.2016


Ответы (4)


Вы можете использовать синтаксис объекта rest/spread:

// We destructure our "this.props" creating a 'styles' variable and
// using the object rest syntax we put the rest of the properties available
// from "this.props" into a variable called 'otherProps' 
const { styles, ...otherProps } = this.props;
const section = cloneElement(this.props.children, {
  className: styles.section,
  // We spread our props, which excludes the 'styles'
  ...otherProps,
});

Я предполагаю, что у вас уже есть поддержка этого синтаксиса на основе вашего кода выше, но имейте в виду, что это предлагаемый синтаксис, который доступен вам через предустановка babel stage 1. Если вы получаете синтаксические ошибки при выполнении, вы можете установить предустановку следующим образом:

 npm install babel-preset-stage-1 --save-dev

А затем добавьте его в раздел пресетов вашей конфигурации babel. Например, в вашем файле .babelrc:

 "presets": [ "es2015", "react", "stage-1" ]

Обновление на основе комментария к вопросу от OP.

Итак, вы говорите, что у вас уже есть переменная styles, объявленная перед этим блоком? Мы можем справиться и с этим делом. Вы можете переименовать свои деструктурированные аргументы, чтобы избежать этого.

Например:

const styles = { foo: 'bar' };

const { styles: otherStyles, ...otherProps } = this.props;
const section = cloneElement(this.props.children, {
  className: otherStyles.section,
  // We spread our props, which excludes the 'styles'
  ...otherProps,
});
person ctrlplusb    schedule 15.06.2016
comment
Я не думаю, что это работает из коробки с пресетом реакции. Было бы полезно, если бы вы объяснили, как настроить Babel, чтобы использовать это. - person Felix Kling; 15.06.2016
comment
Это действительно творческий ответ, я не знал, что это возможно с оператором распространения - person Michael Parker; 15.06.2016

Вы можете использовать магию оператора Object Rest Spread.

const props = { a: 1, b: 2, c: 3 };
const { a, ...propsNoA } = props;
console.log(propsNoA); // => { b: 2, c: 3 }

Итак, в вашем случае это будет:

const { styles, ...propsNoStyles } = this.props;
const section = cloneElement(this.props.children, {
  className: this.props.styles.section
  ...this.propsNoStyles,
});
person am0wa    schedule 11.02.2020
comment
Кажется, это тот же ответ, что и @ctrlplusb - person Fez Vrasta; 11.02.2020
comment
@am0wa все в порядке, но потом es-lint или другие плачут, потому что я просто хотел проигнорировать первый ... не нашел хорошего способа, чтобы он исчез и сделал линтеры счастливыми - person RangerReturn; 14.07.2020
comment
@RangerReturn, вы могли бы использовать // tslint:disable-next-line - person am0wa; 22.07.2020

или вы можете сделать что-то вроде этого...

var newProp = (this.props = {p1, p2,...list out all props except styles});
person user796870    schedule 26.02.2017

Мне нравится ответ ctrlplusb, но вот альтернатива с использованием Object.assign, если вы не хотите добавлять новую предустановку Babel:

const section = cloneElement(this.props.children, {
    className: this.props.styles.section,
    ...Object.assign({}, this.props, {
        styles: undefined
    })
});
person Michael Parker    schedule 15.06.2016
comment
Тогда у вас есть неопределенное свойство - person Fez Vrasta; 15.06.2016
comment
Это не должно иметь значения для вашего приложения. Если вы попытаетесь получить доступ к prop, который не был передан вашему компоненту, значение в любом случае будет undefined. Это почти эквивалентно, при условии, что вы не полагаетесь на существование определенного ключа, предоставленного вашим реквизитам. - person Michael Parker; 16.06.2016