【问题标题】:React.js style mutation error......?React.js 样式突变错误……?
【发布时间】:2018-03-01 21:27:31
【问题描述】:

这就是我正在使用的:
反应: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。考虑事先克隆它。检查Navrender。以前的样式:{display: "block", position: "relative", boxSizing: "border-box", border: 0, outline: 0, width: "100%", padding: "12px 6px", fontSize: "16px ",背景:"#333",颜色:"#eee"}。变异样式:{display:“block”,position:“relative”,boxSizing:“border-box”,border:0,outline:0,width:“100%”,padding:“12px 6px”,fontSize:“16px ",背景:"#494949",颜色:"#eee"}。


任何帮助将不胜感激。谢谢!

【问题讨论】:

标签: javascript reactjs


【解决方案1】:
    component.state.style.input.background = '#494949';
    component.forceUpdate();

此部分非常不正确。

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

其次,forceUpdate 是针对极端情况的钩子。一般来说,如果您发现需要使用它,则意味着您的代码存在严重问题。在这种情况下,这是因为您没有在应该使用 setState 时使用。 setState 总是会导致组件重新评估它的渲染方法并确定它是否需要更新。

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

您可以将这两行替换为以下内容;

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

如果您不使用这种深度嵌套的状态模型,这可能会更简洁,但这种方式仍然非常实用。

【讨论】:

  • 是的。这就是为什么建议不要使用深度嵌套的状态。如果您将 inputStyle 作为状态的顶级对象,则它将改为简单的 return { inputStyle: {...oldState.inputStyle, background: '#494949' } };
【解决方案2】:

代替

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

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

【讨论】:

  • 似乎这种计算对于复杂的状态可能会变得很繁重......虽然这似乎是唯一的方法......(如果只有 component.assignState( ) 也是如此)......
  • 正如@gravityplanx 指出的那样,如果您的组件状态没有那么深嵌套,这会容易得多。此外,状态实际上应该只保存在应用程序过程中发生变化的值。我不确定 venatici 包是如何工作的,但有必要保持它的状态吗?如果没有,您可以轻松地让 state 只保存输入的背景颜色。
猜你喜欢
  • 2017-07-02
  • 2016-11-18
  • 1970-01-01
  • 2021-05-21
  • 2017-02-25
  • 2017-06-08
  • 1970-01-01
  • 2020-10-01
  • 2018-05-25
相关资源
最近更新 更多