【问题标题】:MobX, React Router v4, Route using render function not observing and re-rendering when store changesMobX,React Router v4,使用渲染功能的路由在存储更改时不观察和重新渲染
【发布时间】:2018-03-15 15:07:41
【问题描述】:

使用需要传递给组件的道具的路线,我传递了一个可以从我的商店观察到的布尔值。当这个值改变时,路由渲染的组件不会更新。

<Switch>
    <Route exact path="/" render={()=><MyComponent isLoading={this.props.MyMobxStore.ShowMyComponentLoader} />} />
</Switch>

这个组件是 Observable 并且注入了 MyMobxStore。如果我更改该 observable,则不会重新渲染组件“MyComponent”或通知更改。

如果我在顶级组件上调用任意“setState”,它就会起作用。或者如果我添加一个虚拟元素,例如

<div idk={this.props.MyMobxStore.ShowMyComponentLoader}/>

这使得当前组件重新渲染,使得依赖于这个 observable 的“MyComponent”按预期运行。

我是否缺少明显的解决方案?我可以添加其中一种技巧来使其正常工作。我可以将我的“MyComponent”包装在另一个可观察对象中并以这种方式传递,但这不利于我的设计。虽然没那么重要。在这一点上,这纯粹是学术性的。我想知道为什么它不起作用。

更新

被要求包含更多代码。

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import {inject, observer } from 'mobx-react';
import {MyComponent, CoolChildComponent} from '.coomComponents';

@inject('LoaderStore')
@observer
class App extends Component {
    
    componentWillMount() {
        this.props.LoaderStore.setShowLocalLoader(true);
        setTimeout(() => {
            this.props.LoaderStore.setShowLocalLoader(false);
        }, 5000);
    }
    

    render() {
        return( 
            <div>
            {/* note router container and "with router" wrapper one level up. */}
              <Switch>
                  <Route render={()=>{return <MyComponent isLoading={this.props.LoaderStore.showLocalLoader}><CoolChildComponent/></MyComponent>}} />
              </Switch>
            </div>
        );
    }
}

export default App;

注意,我知道如何解决这个问题。我不明白的是为什么 MobX 没有意识到渲染正在使用 LoaderStore.showLocalLoader

【问题讨论】:

    标签: reactjs mobx


    【解决方案1】:

    尝试以下方法:

    render() {
        const showLocalLoader = this.props.LoaderStore.showLocalLoader
        return( 
            <div>
            {/* note router container and "with router" wrapper one level up. */}
              <Switch>
                  <Route render={()=>{return <MyComponent isLoading={showLocalLoader}><CoolChildComponent/></MyComponent>}} />
              </Switch>
            </div>
        );
    }
    

    这将导致正确的值作为道具发送到路由, 当 observable 嵌套在 render 的返回值中时,有时值的变化不会触发重新渲染。

    让我知道它是否有效

    【讨论】:

    • 宾果游戏。这很有意义。我不知道为什么我没有想到那个。
    【解决方案2】:

    听起来您缺少 MyComponent 的观察者包装器 如果你支持装饰器,你可以使用@observer,否则你应该启用装饰器,如图here

    希望对您有所帮助,如果这是问题,这里有一点解释:

    当您在 mobx 商店中设置 observable 时,您可以通过几种方式对此 observable 的更改做出反应(我只是列出 2 以了解更多选项,请参阅 mobx 文档):

    1. 使用自动运行 - more info
    2. 使用@observable - more info

    这两种方法的工作原理相同,只是在 observable 选项中,渲染函数的工作方式与 autorun 工作方式类似

    如果你在函数中有一个可观察对象,它会在每次函数范围内的可观察对象发生变化时触发它

    祝你好运!

    【讨论】:

    • MyComponent 被标记为 Observable。但这不是问题,如果我直接从 MyComponent 中的商店使用可观察值,它会按预期工作,但如果我将可观察值作为道具传递下去,它不会。我可以通过 3 种方式解决这个问题。我只是不明白当前组件是否正在监视该值的使用,并且我将该值作为渲染函数内的道具传递给子组件。为什么 react/mobx 不触发更新。很明显 mobx x 没有看到它正在被使用。我只是不明白为什么。
    • 如果你可以添加代码或者只是你向下传播 observable 的方式,我可能会更有帮助,只是为了确保,当你说组件是 observable 时,你的意思是观察者?
    • 我添加了更多代码。这是我传递它的方式。我只是不明白为什么这种方式行不通。我已经通过在 周围使用包装器组件解决了这个问题,但我想知道为什么从根本上这不起作用。
    猜你喜欢
    • 2017-12-11
    • 1970-01-01
    • 2018-06-06
    • 2018-10-18
    相关资源
    最近更新 更多