React.js样式突变错误......?

时间:2017-09-20 17:36:26

标签: javascript reactjs

这就是我正在使用的:
反应:15.6.1

触发onChange时会发生错误。

组件文件:

import React, { Component } from 'react';

var defaults = {
    text: {
        placeholder: '',
        label: ''
    },
    style: {
        wrapper: {
            display: 'block',
            padding: '9px 0'
        },
        label: {
            display: 'block',
            padding: '0px 8px 4px',
            color: require('macros').theme.text.info
        },
        input: {
            display: 'block',
            position: 'relative',

            boxSizing: 'border-box',
            border: 0,
            outline: 0,
            // border: `1px solid ${ require('macros').theme['text field'].border }`,
            width: '100%',
            padding: '12px 6px',

            fontSize: '16px',

            background: require('macros').theme['text field'].background,
            color: require('macros').theme.text.info
        },
        active: {
            input: require('macros').theme['text field'].active.background
        }
    },
    type: 'text',
    onChange: function() {}
};

export default class Nav extends Component {
    constructor(props) {
        super(props)
        var component = this;

        component.state = require('venatici').object.combine(defaults, component.props);
        component.onChange = component.onChange.bind(this);
    }

    onChange(event) {
        var component = this;
        component.state.onChange(event.target.value);

        component.state.style.input.background = '#494949';
        component.forceUpdate();
    }

    render() {
        var component = this;

        return (
            <text-field
                ref='outer'
                style={ component.state.style.wrapper }
            >
                <label style={ component.state.style.label }>{ component.state.text.label }</label>
                <input
                    name={ component.state.type }
                    type={ component.state.type }
                    style={ component.state.style.input }
                    placeholder={ component.state.text.placeholder }
                    onChange={ component.onChange }
                ></input>
            </text-field>
        );
    }

    componentDidMount() {

    }
}

错误

警告:input传递了之前已发生变异的样式对象。不推荐使用变异style。考虑事先克隆它。查看render的{​​{1}}。上一个样式:{display:&#34; block&#34;,position:&#34; relative&#34;,boxSizing:&#34; border-box&#34;,border:0,outline:0,width:& #34; 100%&#34;,填充:&#34; 12px 6px&#34;,fontSize:&#34; 16px&#34;,背景:&#34;#333&#34;,颜色:&#34 ;#EEE&#34;}。变异样式:{display:&#34; block&#34 ;, position:&#34; relative&#34;,boxSizing:&#34; border-box&#34;,border:0,outline:0,width:& #34; 100%&#34;,填充:&#34; 12px 6px&#34;,fontSize:&#34; 16px&#34;,背景:&#34;#494949&#34;,颜色:&#34 ;#EEE&#34;}

非常感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

而不是

component.state.style.input.background = '#494949';
component.forceUpdate();

DO

const inputStyles = Object.assign({}, component.state.style.input, { background: '#494949' });
const styles = Object.assign({}, component.state.style, { input: inputStyles });
component.setState({ style: styles });

答案 1 :(得分:2)

    component.state.style.input.background = '#494949';
    component.forceUpdate();

此部分非常不正确。

首先,您不应该直接更改组件状态中的任何值。允许您更改状态的唯一方法是使用setState挂钩。

其次,forceUpdate是极端边缘情况的钩子。通常,如果您发现需要使用它,则表示代码中存在严重问题。在这种情况下,这是因为您没有应该使用setStatesetState将始终使组件重新评估它的呈现方法并确定它是否需要更新。

最后,虽然没有“错误”,但没有理由使用作业component = this。如果您处于this关键字不再是组件的上下文中,那么再次表明您的代码结构存在问题。

您可以使用以下内容替换这两行;

this.setState((oldState) => { 
    return {
        ...oldState, 
        style: { 
            ...oldState.style, 
            input: {
                ...oldState.style.input,
                background: '#494949'
            }
        }
    }
});

如果你没有使用这种深度嵌套的状态模型,这可能会更加清晰,但它仍然非常实用。