Uncaught TypeError: Невозможно назначить только для чтения свойство '' объекта '# <Object>' - PullRequest
0 голосов
/ 29 января 2019

Я не знаю, какая разница в этом коде.класс a является компонентом, а example - example.js

import React, {Component} from 'react';

const styles = {
    border: {
        display: 'inline-block',
        height: '19px',
        padding: '1px 8px 0',
        border: '2px solid',
        borderRadius: '12px',
        lineHeight: '20px',
        fontSize: '14px',
        verticalAlign: 'top',
    },
    default: {
        display: 'inline-block',
        height: '20px',
        padding: '1px 10px 0',
        borderRadius: '10px',
        lineHeight: '21px',
        fontSize: '13px',
        verticalAlign: 'top',
    },
    state: {
        display: 'inline-block',
        width: '14px',
        height: '13px',
        paddingTop: '1px',
        lineHeight: '14px',
        fontSize: '11px',
        color: '#fff',
        letterSpacing: '-0.5px',
        textAlign: 'center',
        verticalAlign: 'top',
    }
};

class A extends Component {
    static defaultProps = {
        type: 'default',
    };

    render() {
        const {
            label,
            style,
            type,
            ...other
        } = this.props;


        switch (type) {

            case 'border':
                elementStyle = styles.border;
                break;
            case 'default':
                elementStyle = styles.default;
                break;
            case 'state':
                elementStyle = styles.state;
                break;
        }

        return (
            <span style={Object.assign(elementStyle, style)} {...other}>{label}</span>
        );
    }
}

export default A;

, а example code - example.js

import A from './A';

    export default class Example extends React.Component {
        render() {
            return (
                <div>
                    <A style={{background: '#fe6969', color: '#fff'}} /> &nbsp;
                    <A style={{background: '#ff8137', color: '#fff'}} /> &nbsp;
                    <A  style={{background: '#fcb400', color: '#fff'}} /> &nbsp;
                </div>
            );
        }
    }

эта кодовая ошибка Uncaught TypeError: Невозможно назначить только для чтения свойство 'background'объекта' # '

я использую babel-loader 8, babel7, webpack4

, если я исправлю объект Object.assgin ({}, elementStyle, style) работает.Я думаю, что эта ошибка возникает при повторной визуализации компонента.я не знаю, почему эта ошибка ...

пожалуйста, помогите мне.

1 Ответ

0 голосов
/ 29 января 2019

Все, что вам нужно сделать, это объединить / объединить два объекта, как этот, используя распространение

{{...elementStyle, ...style}}  or

{Object.assign({}, elementStyle , style) }

Вы должны понимать природу того, как работает Object.assign.Он возвращает целевой объект как возвращаемое значение его операции.

Итак, в первом синтаксисе:

Object.assign({}, elementStyle , style)

вы создаете новый объект с перечисляемыми свойствами elementStyle и style .

Если вы сделаете это:

Object.assign(elementStyle, style)

Тогда elementStyle сам по себе является целевым объектом, поэтому он будет видоизменяться и будет возвращен из Object.assign.

Вот пример того, что я имею в виду.

Пример 1:

// With no new target object
const original = [{id:1}, {id:2}, {id:3}];

const newArray = original.map(elem => {
  return Object.assign(elem, {id:2});
});

console.log('Original object has changed');
console.log(original);

//------------------------------

// With a new target object
const original2 = [{id:1}, {id:2}, {id:3}];

const newArray2 = original2.map(elem => {
  return Object.assign({}, elem, {id:2});
});

console.log('Original object has not changed');
console.log(original2);

Пример 2:

var styles =  {
  circle: {backgroundColor: 'yellow', height: '1005', width: '100%'},
  circleA: {backgroundColor: 'blue'},
};

Таким образом, нам нужно, чтобы у всех окружностей по умолчанию был какой-то стиль окружности, но нам нужно изменить некоторое свойство,

// background yellow
<div style={styles.circle}></div>

// background  blue
<div style={Object.assign(styles.circle, styles.circleA)}></div>

// expeted background yellow, but it's blue. cus styles.circle still have it's merged value
<div style={styles.circle}></div>

Решением является передача пустого объекта в Object.assign ().Делая это, вы говорите методу для создания NEW объекта с объектами, которые вы передаете ему .

Пример 3:

const obj1 = {
  name: "J"
}

const obj2 = {
  gander: "m"
}

// Here, obj1 is the same after the Object.assign call
console.log(Object.assign({}, obj1, obj2));
console.log(obj1)
console.log(obj2)

console.log("without empty obj passed")

// Note that after this call, obj1 holds both keys. So this will mutate it:
console.log(Object.assign(obj1, obj2));
console.log(obj1) // This is different now
console.log(obj2)

В вашем случае,

`<A propstyle={{background: '#fe6969', color: '#fff'}} />

<A propstyle={{background: '#ff8137', color: '#fff'}} /> ` 

компонент A, определенный дважды в Parent, означает, что мы получим два круга, а дочерний компонент будет визуализироваться дважды.

, а в дочернем компоненте вы определили, как показано ниже:

<span style={Object.assign(elementStyle , style) }{...other}>{label}</span>

первый рендер:

Object.assign перезаписывает свойства справа налево реквизиты style для elementStyle, здесь elementStyle сам по себе является целевым объектом, который будет тем, что возвращается из Object.assign.

стиль реквизита: { background: "#fe6969", color: "#fff" }

elementStyle: { background: "#fe6969", borderRadius: "10px", color: "#fff" }

Второй рендер:

Object.assign пытается перезаписатьсвойства справа налево, но elementStyle имеет { background: "#fe6969", borderRadius: "10px", color: "#fff" }

и Object.assign все еще находится в цикле (вспомните пример 1 .map ())

стиль реквизитов: { background: "#ff8137", color: "#fff" }

выдано сообщение об ошибке: 'Ошибка типа: невозможно присвоить только для чтения свойство' background 'объекта' при {Object.assign(elementStyle , style) }, поскольку нет нового целевого объекта.

, пожалуйста, найдите полный код здесь

Надеюсь, это поможет. читать дальше

...