【问题标题】:Importing redux store is undefined (loading order issue?)导入 redux 存储未定义(加载顺序问题?)
【发布时间】:2018-03-15 12:37:04
【问题描述】:

更新 2 - 添加显示问题的最小“工作”示例

我在仍然显示问题的同时尽可能地缩减了项目,以便人们在感兴趣的情况下尝试想法/调试 github:store_import_test

错误发生在:request.js

注意:我知道赏金即将到期,但如果发生这种情况,我会重新启用它。我非常感谢到目前为止提出的所有想法/帮助!

结束更新 2

更新 1 - 用途说明:

我想在“实用程序功能”中访问商店中的一个值(可以改变超时)。根据redux docssubscribe是一个有效的选项。

结束更新

我正在尝试将我的 redux-store 导入组件之外(在 request.js 中,见下文),类似于:What is the best way to access redux store outside a react component?

但是,所有这些解决方案(包括https://github.com/reactjs/redux/issues/776)都不起作用,因为我的request.js 尝试在createStore()store.js 中调用之前导入商店,导致store 成为undefined

我的目录结构是这样的

 .  
 ├── app  
 │   ├── api  
 │   ├── network 
 │   |    └── request.js 
 │   ├── app.js  
 │   ├── store.js  
 ├── index.android.js  
 ├── index.ios.js

index.android/ios.js 是入口点,只需加载 app.js

index.android/ios.js

import App from './app/app'

app.js

import store from './store'
class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                    <RootStackNavigation />
            </Provider>
        )
    }
} 

store.js

...
const store = createStore(reducer, initialState, middleware())
export default store

request.js

import store from '../../store'
store.subscribe(listener)
...
const someFunc(){}
export default someFunc

我的想法/我的尝试/我迷路的地方

注意:request.js 中的store 导入路径有效,请仔细检查 注意2:store 可用于app.js 和程序的其余部分

我认为request.js 中的import store from '../../store' 会触发const store = createStore(reducer, initialState, middleware()) 行,但显然它似乎确实如此。

尝试 1

我也尝试这样导出商店:

export const store = createStore(reducer, initialState, middleware())

并将其导入request.js 为:

import {store} from '../../store

认为“聪明”的默认加载可能会产生一些我不知道/不理解的魔力。同样的错误,未定义

尝试 2getStore() 添加到 store.js

let store = null
store = createStore(reducer, initialState, middleware())
export function getStore() {
    if (store == null) {
        store = createStore(reducer, initialState, middleware())
    }
    return store
}

export default store

不起作用,createStore 的参数尚未初始化。

我一定是误解了加载过程或将其与 python 的加载过程混合在一起,但是是什么阻止了它的工作?其他人似乎成功地使用了相同的解决方案(参见上面提到的帖子)。

【问题讨论】:

  • 我认为您正在尝试使用 react 的状态(使用 Redux 管理)而不使用 react,这不会发生。您是否考虑将请求作为中间件放入应用程序?
  • 如果您查看我链接的 SO,您会看到人们成功地按照我的要求进行操作。例如这个解决方案stackoverflow.com/a/38480550/3869515 我基本上是在尝试做与那个解决方案相同的事情。鉴于他们的成功,我认为这应该是可能的
  • 在您的示例中,缺少侦听器功能,我猜您忘记粘贴了?
  • 我省略了那部分,因为我试图在不丢失太多信息的情况下尽可能地减少它。我通过在两者之间添加“...”来澄清它。错误消息类似于“can't call subscribe on undefined”,调试时显示 store 未定义。
  • 您能否在request.js 中提供有关listener 的反馈?

标签: javascript react-native redux


【解决方案1】:

发现问题。我是对的——这是一个循环。在store.js 中,您需要reducers/index.js,然后是navigation.js,然后是../navigators/RootNavigationConfiguration,这需要Home.js,这需要/api/network,它需要request.js,它需要store,此时尚未初始化。在导出之前尝试将 store.subscribe(listener)listener 函数一起移动到 store.js。不要忘记从request.js 中删除import store.js

【讨论】:

  • 循环中的好发现。我认为将所有此类情况转移到store.js 是不可行的。此外,在我目前的情况下,listener() 应该对我在request.js 中需要的数据进行操作。即使我只是为了这种情况移动它,那么我必须在store.js 中公开额外的数据,在request.js 中导入它,然后我们有另一个循环,对吗?如果您查看request.js,那么我希望我的base_url@ 第32 行指向rpcUrl 的值,反过来rpcUrl 将由listener() 修改,如果network.net 在商店中更改。希望这仍然有意义。
  • 简而言之,我想根据商店中的network.net 值即时修改base_url
  • @justsome 我想说的是,这是反模式。你在使用 Redux thunk 吗?如果是这样,从商店获取 url 并将其传递给 api 方法。我推荐的另一种方法是使用 redux saga 并将其传递给 api 方法。
  • 我正在使用 redux-saga,但每次网络调用都从商店传递 network.net 值似乎很荒谬。 store.subscribe() 函数的存在是有原因的。我在主帖中链接的示例显示人们在做完全相同的事情,但不是为了更改 base_url 而是为了添加令牌。我想我应该研究如何避免从我的导航减速器加载RootNavigationConfiguration(如果可能的话)
  • 给store.subscribe()设置一个超时时间怎么样?
【解决方案2】:

您可以简单地在 App 组件中创建您的商店以减少复杂性,并将其传递给子组件。

let store = createStore(reducers);

export class App extends Component {
    constructor() {
        super();
        this.state = store.getState();
        this.syncState = this.syncState.bind(this);
    }

    syncState() {
        this.setState(store.getState());         
    }

    componentDidMount() {
        this.setState(store.getState());
        const unsubscribe = store.subscribe(this.syncState);
    }

    render() {
        return (
            <Provider store={store}>
                <AppNavigator/>
            </Provider>
        )
    }
}

然后您的子组件需要从 react-redux 导入连接。

import {connect} from 'react-redux';

export class SubComponent extends Component {
  //Implementation
  //this.props.myLocalCopy - gives you the value
  //this.props.someTask(data) - Updates the store and updates your props.
}

function mapStateToProps(state) {
    return {
        myLocalCopy: state.someStoreProperty
    };
}

function mapDispatchToProps(dispatch) {
     return {
         someTask: (data) => {
             dispatch(actionCreators.someTask(data));
         }
     }
}

export default connect(mapStateToProps, mapDispatchToProps)(SubComponent)

这将帮助您在整个工作流程中将应用状态与商店同步。 希望有帮助! :)

【讨论】:

    【解决方案3】:

    你是不是在 request.js 中写了“../../store”,但是你的目录结构说它应该是“../store”。

    【讨论】:

    • 你是对的。但是,这只是在我编辑tree 输出时出错,因为network 文件夹实际上是api 的子文件夹。实际导入是正确的。我已经更新了帖子以包含一个展示该问题的最小示例项目。
    【解决方案4】:

    我觉得你想制作反模式。您的需求正在我耳边低语“传奇”,但让我们照原样为您提供帮助。

    我想从 github 向您提供已关闭的问题,但我想明确“他们”在哪里存储 - import {store} from "store"; 导出 const store = configureStore(); 并配置存储(以避免误解)返回 redux.createStore(...)

    在你知道我写了什么之后 - 你可以理解“他们”在写什么therethere

    【讨论】:

    • 我不明白与链接的 github 问题的关系。我想在“实用程序功能”中访问商店中的值(可以更改超时)。根据redux docssubscribe 是一个有效的选项。我不会像链接的那些问题那样尝试调度操作或修改状态。
    • 我的理解是,您想要创建在商店更新时执行某些操作的函数
    • 没问题。我更新了问题以添加我的额外解释,希望避免进一步的混淆。 store.getState()...request.js 中不起作用,因为此时 storeundefined。这就是我面临的实际问题。一旦解决了,我就可以做任何我想做的事情:)
    • 继续发布另一个问题,看看如何实现这个很有趣
    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 2017-07-12
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    相关资源
    最近更新 更多