首页 > 解决方案 > 使用全局 JS 对象作为 React 组件的状态

问题描述

我们正在构建一个模拟工具,并试图替换我们当前使用 React 处理弹出窗口的实现。

问题是我们的弹出组件的状态设置为

this.state = connections[this.props.id]

该对象是一个存在的全局对象,在单独的 js 文件中创建和更新,如果我进入控制台并将连接 [this.props.id].name 从“junction 15”更改为“junction 12”,则更改不会立即渲染。我必须关闭并重新打开弹出窗口,以便它呈现正确的信息。

这是我们的架构师想要的,他解释的方式是,他需要对我们的连接对象进行任何更改,如果它是打开的,则反应需要反映在我们的弹出窗口中,但是如果状态设置为标记并且我修改通过控制台在对象中标记的名称,我不明白为什么它没有在 React 中自动更新

我已经尝试过尝试使用生命周期方法、redux、mobx、js 代理、反应上下文,但我仍在学习,我认为我让这变得比它应该的更复杂。

这是我们带有组件的简单弹出窗口:

let globalValue = 'initial'

class ReactButton extends React.Component {
    constructor(props) {
        super(props);

        this.state = connections[this.props.id];
        this.changeName = this.changeName.bind(this);
    }
    updateOutsideReactMade() {
    this.setState(state);
    // this.forceUpdate();
}
    changeName(newName) {
        connections[this.props.id].name = newName;
        this.setState(connections[this.props.id]);
    }

    // ignore this, this was my attempt at using a lifecycle method
    //componentDidUpdate(prevProps) {
        // Typical usage (don't forget to compare props):
    //    if (this.props.name !== prevProps.name) {
    //        this.setState(this.props.name);
    //    }
    //}

    render() {
        return (
            <div>
                <Input onChange={this.changeName} />
                <Header name={this.state.name}
                        id={this.state.id}
                />
            </div>
        );
    }
}

function renderReactButton(iddd, type){
    ReactDOM.render(
    <ReactButton id={iddd} />,
    document.getElementById(`react-component-${type}-${iddd}`)
    );
}




   class Header extends React.Component {
    constructor(props) {
        super(props);
    }


    render() {
        return (
            <h1>{this.props.name}
                {this.props.id}</h1>
        );
    }
}


class Input extends React.Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
    }


    handleChange(e) {
        const name = e.target.value;
        this.props.onChange(name);
    }

    render() {
        return (
            <input onChange={this.handleChange}/>
        );
    }
}

所以我的问题是我如何能够使用一个全局的对象(连接)作为我的反应状态,并且如果某些东西修改了 React 之外的数据,它将反映在 DOM 上。现在,我们可以通过反应弹出窗口更改名称,但如果我们通过控制台更改名称,它不会更新。感谢你们!

****更新**** 2018 年 8 月 15 日我将每个新对象包装为代理,因为它被输入到我的数组中。

connections[key] = new Proxy(polyLine, handleUpdatesMadeToMarkersOutsideOfReact);

我设置了一个处理程序:

let handleUpdatesMadeToMarkersOutsideOfReact = {
    get: (connections, id) => {

        return connections[id];
    },

    set: (connections, id, value) => {
        //trigger react re-render
        console.log('inside set');

        //trigger react to update

        return true;
    }

};

现在我一直试图让处理程序触发我的反应组件进行更新。我为我的组件创建了一个强制更新的类函数,但我很难以我们设置它的方式访问它。

标签: javascriptreactjs

解决方案


通常state是一个对象 - 提供现有对象是可以的。React 需要setState使用能够处理生命周期,fe 渲染更新状态。从控制台修改状态对象不会让反应做出反应;)

你需要某种观察者,来告诉反应而不是改变数据并强制渲染(调用this.forceUpdate())。


推荐阅读