Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 嵌套的可观察更改时组件不重新渲染_Reactjs_Observable_Mobx_Mobx React - Fatal编程技术网

Reactjs 嵌套的可观察更改时组件不重新渲染

Reactjs 嵌套的可观察更改时组件不重新渲染,reactjs,observable,mobx,mobx-react,Reactjs,Observable,Mobx,Mobx React,将节点添加到列表中,但组件不会重新渲染。Mobx Chrome扩展开发工具说这是一个依赖项,但出于某些原因,仍然没有反应 按钮根据节点是否在列表中呈现“添加”或“删除”。它不会重新渲染,除非我移动到另一个组件,然后再次打开该组件 按钮: @inject("appStore") @observer class EntityTab extends Component { ... render() { return ( ...

将节点添加到列表中,但组件不会重新渲染。Mobx Chrome扩展开发工具说这是一个依赖项,但出于某些原因,仍然没有反应

按钮根据节点是否在列表中呈现“添加”或“删除”。它不会重新渲染,除非我移动到另一个组件,然后再次打开该组件

按钮:

@inject("appStore") @observer
class EntityTab extends Component {
...
    render() {
         return (
            ...
            {/* BUTTONS */}
            { this.props.appStore.repo.canvas.graph.structure.dictionary[id] !== undefined ?
                <div onClick={() => this.props.appStore.repo.canvas.graph.function(id)}>
                     <p>Remove</p>
                </div>
                :
                <div onClick={() => this.props.appStore.currRepo.canvas.otherfunction(id)}>
                    <p>Add</p>
                </div>
            }
            ...
          )
    }
}
然后我们转到这个函数

@observable graph = new Graph();
...
@action
    otherfunction = (idList) => {
        // Do nothing if no ids are given
        if (idList === null || (Array.isArray(idList) && idList.length === 0)) return;

        // If idList is a single value, wrap it with a list
        if (!Array.isArray(idList)) { idList = [idList] }

        let nodesToAdd = [];
        let linksToAdd = [];

        // Add all new links/nodes to graph
        Promise.all(idList.map((id) => { return this.getNode(id, 1) }))
            .then((responses) => {
                for (let i = 0; i < responses.length; i++) {
                    let res = responses[i];
                    if (res.success) {
                        nodesToAdd.push(...res.data.nodes);
                        linksToAdd.push(...res.data.links);
                    }
                }
                this.graph.addData(nodesToAdd, linksToAdd, idList, this.sidebarVisible);
            });
    };
    @observable map = new Map(); 
    @observable map2 = new Map(); 
    @observable dictionary = {}; 
    @observable dictionary2 = {}; 
    @observable allNodes = []; 
    @observable allLinks = []; 

    ...

    @action
    addNodes = (nodes=[]) => {
        if (!nodes || nodes.length === 0) return;
        nodes = utils.toArray(nodes);

        // Only consider each new node if it's not in the graph or a duplicate within the input list
        nodes = _.uniqBy(nodes, (obj) => { return obj.id; });
        const nodesToConsider = _.differenceBy(nodes, this.allNodes, (obj) => { return obj.id; });

        // Add nodes to map
        let currNode;
        for (let i = 0; i < nodesToConsider.length; i++) {
            currNode = nodesToConsider[i];
            this.map.set(currNode.id, new Map());
            this.map2.set(currNode.id, new Map());
            this.dictionary[currNode.id] = currNode;
        }

        // Update internal list of nodes
        this.allNodes = this.allNodes.concat(nodesToConsider);
    };
无论如何,addToGraphFromIds会触发

this.graph.addData(nodesToAdd, linksToAdd);
然后我们去那个函数

@action
    addData = (nodes, links) => {
        this.structure.addNodes(nodes);
        this.structure.addLinks(links);
    };
触发

this.props.appStore.currRepo.canvas.otherfunction(id)
this.structure.addNodes(nodes);
这导致了这个功能

@observable graph = new Graph();
...
@action
    otherfunction = (idList) => {
        // Do nothing if no ids are given
        if (idList === null || (Array.isArray(idList) && idList.length === 0)) return;

        // If idList is a single value, wrap it with a list
        if (!Array.isArray(idList)) { idList = [idList] }

        let nodesToAdd = [];
        let linksToAdd = [];

        // Add all new links/nodes to graph
        Promise.all(idList.map((id) => { return this.getNode(id, 1) }))
            .then((responses) => {
                for (let i = 0; i < responses.length; i++) {
                    let res = responses[i];
                    if (res.success) {
                        nodesToAdd.push(...res.data.nodes);
                        linksToAdd.push(...res.data.links);
                    }
                }
                this.graph.addData(nodesToAdd, linksToAdd, idList, this.sidebarVisible);
            });
    };
    @observable map = new Map(); 
    @observable map2 = new Map(); 
    @observable dictionary = {}; 
    @observable dictionary2 = {}; 
    @observable allNodes = []; 
    @observable allLinks = []; 

    ...

    @action
    addNodes = (nodes=[]) => {
        if (!nodes || nodes.length === 0) return;
        nodes = utils.toArray(nodes);

        // Only consider each new node if it's not in the graph or a duplicate within the input list
        nodes = _.uniqBy(nodes, (obj) => { return obj.id; });
        const nodesToConsider = _.differenceBy(nodes, this.allNodes, (obj) => { return obj.id; });

        // Add nodes to map
        let currNode;
        for (let i = 0; i < nodesToConsider.length; i++) {
            currNode = nodesToConsider[i];
            this.map.set(currNode.id, new Map());
            this.map2.set(currNode.id, new Map());
            this.dictionary[currNode.id] = currNode;
        }

        // Update internal list of nodes
        this.allNodes = this.allNodes.concat(nodesToConsider);
    };
正如我们在第一个代码框中看到的

this.props.appStore.repo.canvas.graph.structure.dictionary[id] !== undefined
当我们添加当前节点时,应该会导致按钮更改值。当我登录或使用mobx chrome扩展开发工具时,节点出现在字典中,但我必须切换选项卡,然后按钮将重新渲染。我试过使用其他的线路,比如

this.props.appStore.repo.canvas.graph.structure.allNodes.includes(node)

但这也不行。我完全陷入困境,需要帮助。我有一种感觉,这与嵌套的可观察对象有关,也许标记@observable不够好,但不太确定。repo和canvas被标记为可观察对象,并实例化一个新的repo()对象和新的canvas()对象,很像在getNodes中创建的new Node()。

看起来Edward解决了它,类似于Redux。看起来你必须用字典创建一个新对象,而不是修改它。我猜这是因为已经定义了key currNode.id(作为未定义的值),我们只是将其修改为currNode。这是我的猜测,不管它现在是否有效

Mobx(v4)不跟踪可观察对象中条目的添加或删除,除非使用了
observable.map
。或者升级到
mobxv5
应该可以解决这个问题。 对于您的特定问题,您可以尝试:

@observable nodeIdToNodeData = {};

//...
  this.nodeIdToNodeData = {...this.nodeIdToNodeData, [currNode.id]: currNode};
或者尝试升级到
mobxv5


更多信息

而不是
此.nodeIdToNodeData[currNode.id]=currNode
try
this.nodeIdToNodeData={…this.nodeIdToNodeData,currNode.id:currentNode}这就解决了问题,谢谢!我想我需要创建一个新对象,而不是修改现有的.Yep。它只对数组和对象进行浅层比较,因此您需要更改引用,否则它将无法识别更改。请您将答案标记为正确答案,以便代码中存在类似问题的其他人可以轻松找到它。