为什么ReactJs更新全局变量?

时间:2018-02-08 21:16:04

标签: javascript reactjs

我是ReactJs的新手,我真的不知道如何向你解释这个问题,但是我正在研究一个反应应用程序,而我正在尝试创建一个表单生成器组件,而我成功创造了它。但是当我尝试在任何其他组件中使用它时,每件事情都会以一种奇怪的方式起作用:(例如,它更新了全局var并且我不知道这是怎么回事。我的代码:

fields.js

/**
 *
 * React component that render a control fields using a JSON schema.
 *
 * @file crezmo-fields.js
 * @summary React forms component
 * @author CREZMO <crezmo.com>
 *
 */
class CrezmoFields extends React.Component {

    /**
    * constructor.
    *
    * @since    1.0.0
    * @return   {void}
    */
    constructor (props){
        super(props);
        this.state = {
            fields : this.props.fields            
        };
        this.handleChange = this.handleChange.bind(this);
    }

    /**
    * Render.
    *
    * @since    1.0.0
    * @return   {ReactElement}
    */
    render (){
        return (
            <div>
                {this.state.fields.map((field , index)=>{

                    switch (field.type) {
                        case 'text' : {
                            console.log(this);
                            return this.TextField(field , index);
                            break;
                        }
                    }

                })}
            </div>
        )
    }


    /**
    * Handle Changes.
    *
    * @since    1.0.0
    * @return   {void}
    */
    handleChange (index , new_value){
        // Create an updated field object
        const updated_field = this.state.fields[index];
        updated_field.value = new_value;

        // Create an updated fields object
        const updated_fields = this.state.fields;
        updated_fields[index] = updated_field;

        // Update the component 
        this.setState({fields : updated_fields});

        // Pass data to parent
        (typeof(this.props.hasChanged) === "function" && this.props.hasChanged(this.state.fields))

    }


    /**
    * Text field.
    *
    * @since    1.0.0
    * @param    {object}        data - the field data.
    * @param    {number}        field index number in state.fields
    * @returns  {ReactElement}  a react element of the field
    */
    TextField = (data , index) => {
        const self = this;
        return (
            <div key={index} className={`cf-field cf-${data.type} cf-id-${data.id}`}>
                <label htmlFor={data.id}>
                    {data.title}
                </label>
                <div className="cf-control-wraper">
                    <input 
                        type='text'
                        placeholder = {data.placeholder}
                        name={data.id}
                        value={data.value}
                        onChange={
                            (e) => {
                                self.handleChange(index , e.target.value);
                            }
                        }
                    />
                </div>
                <span className="cf-field-desc">{data.description}</span>
            </div>
        )
    };

}

app.js

var fields = [ //why is this array getting updated when i type in the input field ? 
    {
        type : 'text',
        id : "my_id",        
    }
];

class TestForms extends React.Component {

    /**
    * constructor.
    *
    * @since    1.0.0
    * @return   {void}
    */
    constructor (props){
        super(props);
        this.state = {
            formfields: this.props.fields
        };
    }


    render (){
        return (
            <div>
                <CrezmoFields fields={this.state.formfields}
                    hasChanged={(state)=>{
                        this.setState({formfields: state})
                    }} 
                />
            </div>
        )
    }

}

ReactDOM.render(
    <TestForms fields={fields}/>,
    document.getElementById('app')
);

我错过了什么? 在此先感谢:)

2 个答案:

答案 0 :(得分:6)

因为你从不复制数组。

Javascript对象通过引用传递,因此传递一个对象仍然会改变原始对象。

答案 1 :(得分:2)

这实际上与React无关,这是因为,你传递的是一个数组,而对象/数组是通过引用传递的,所以这意味着你没有传递一个新的数组,而是你正在改变你的初始数组因为它只是向下传递数组的引用,而不是新的数组。 Fields本身是一个在引用时传递的数组,但它也包含也通过引用传递的对象。所以与React无关,只是简单的Javascript东西:)