Javascript 为什么ReactJs要更新一个全局变量?

Javascript 为什么ReactJs要更新一个全局变量?,javascript,reactjs,Javascript,Reactjs,我是ReactJs新手,我真的不知道如何向你们解释这个问题,但我正在开发ReactJs应用程序,我试图制作一个表单生成器组件,我成功地创建了它。但当我尝试在任何其他组件中使用它时,所有事情都开始以一种奇怪的方式运行:(例如,它正在更新一个全局变量,我不知道这是如何发生的。我的代码: fields.js /** * * React component that render a control fields using a JSON schema. * * @file crezmo-fie

我是ReactJs新手,我真的不知道如何向你们解释这个问题,但我正在开发ReactJs应用程序,我试图制作一个表单生成器组件,我成功地创建了它。但当我尝试在任何其他组件中使用它时,所有事情都开始以一种奇怪的方式运行:(例如,它正在更新一个全局变量,我不知道这是如何发生的。我的代码:

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>
        )
    };

}
/**
*
*使用JSON模式呈现控制字段的React组件。
*
*@file crezmo-fields.js
*@summary-React-forms组件
*@作者克雷兹莫
*
*/
类CrezmoFields扩展了React.Component{
/**
*构造器。
*
*@自1.0.0以来
*@return{void}
*/
建造师(道具){
超级(道具);
此.state={
字段:this.props.fields
};
this.handleChange=this.handleChange.bind(this);
}
/**
*渲染。
*
*@自1.0.0以来
*@return{ReactElement}
*/
渲染(){
返回(
{this.state.fields.map((字段,索引)=>{
开关(字段类型){
案例“文本”:{
console.log(this);
返回此.TextField(字段,索引);
打破
}
}
})}
)
}
/**
*处理变化。
*
*@自1.0.0以来
*@return{void}
*/
handleChange(索引,新值){
//创建更新的字段对象
const updated_field=this.state.fields[index];
更新的_field.value=新的_值;
//创建更新的字段对象
const updated_fields=this.state.fields;
更新的_字段[索引]=更新的_字段;
//更新组件
this.setState({fields:updated_fields});
//将数据传递给父级
(typeof(this.props.hasChanged)==“函数”&&this.props.hasChanged(this.state.fields))
}
/**
*文本字段。
*
*@自1.0.0以来
*@param{object}data-字段数据。
*@param{number}state.fields中的字段索引号
*@返回{ReactElement}字段的react元素
*/
TextField=(数据、索引)=>{
const self=这个;
返回(
{data.title}
{
自处理变化(索引,即目标值);
}
}
/>
{data.description}
)
};
}
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')
);
var fields=[//为什么在输入字段中键入时会更新此数组?
{
键入:“文本”,
id:“我的id”,
}
];
类TestForms扩展了React.Component{
/**
*构造器。
*
*@自1.0.0以来
*@return{void}
*/
建造师(道具){
超级(道具);
此.state={
formfields:this.props.fields
};
}
渲染(){
返回(
{
this.setState({formfields:state})
}} 
/>
)
}
}
ReactDOM.render(
,
document.getElementById('app')
);
我错过了什么?
提前感谢:)

因为您从不复制阵列


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

这与React实际上无关,因为您传递的是数组,而对象/数组是通过引用传递的,因此这意味着您没有传递新数组,而是对传递的初始数组进行变异,因为它只是传递数组的引用,而不是新数组。字段本身是一个通过引用传递的数组,但它也包含通过引用传递的对象。所以与React无关,只是简单的Javascript内容:)

你好,谢谢你的回答,但我仍然不知道如何解决这个问题?你能告诉我在这种情况下该怎么办吗?再次感谢。为了快速查看,请尝试删除this.state={fields:this.props.fields};然后使用:this.props.fields.map,然后当您更新时,您将在状态中创建一个新属性,而不是更改道具,因为我可以看到您正在更改状态,这与您通过引用传递的数组相同。我花了一整天的时间试图解决它:)非常感谢:)很高兴我能提供帮助,尽管有一条建议,开始学习自下而上,而不是自上而下:)从技术上讲,它们是通过值传递的引用。