简体   繁体   中英

React.js style mutation error…?

This is what I'm working with:
react: 15.6.1

The error happens when onChange is triggered.

Component File:

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() {

    }
}

Error

Warning: input was passed a style object that has previously been mutated. Mutating style is deprecated. Consider cloning it beforehand. Check the render of Nav . Previous style: {display: "block", position: "relative", boxSizing: "border-box", border: 0, outline: 0, width: "100%", padding: "12px 6px", fontSize: "16px", background: "#333", color: "#eee"}. Mutated style: {display: "block", position: "relative", boxSizing: "border-box", border: 0, outline: 0, width: "100%", padding: "12px 6px", fontSize: "16px", background: "#494949", color: "#eee"}.


Any help would be greatly appreciated. Thanks!

Instead of

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 });
    component.state.style.input.background = '#494949';
    component.forceUpdate();

This section is very incorrect.

First of all, you should never change any value in the state of your component directly. The one and only way you are allowed to change the state is by using the setState hook.

Second, forceUpdate is a hook for extreme edge cases. In general, if you find you need to use it, it means there is a serious problem in your code. In this case, that is because you are not using setState when you should. setState will always cause the component to re-evaluate it's render method and determine whether or not it needs to update.

Lastly, while not "wrong", there's no reason to use the assignment component = this . If you're in a context where the this keyword is no longer the component then, again, that indicates a problem with your code structure.

You could replace those two lines with the following;

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

This could be a lot cleaner if you didn't use such deeply nested state models, but it's still very functional this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM