从组件外部的html按钮调用store.dispatch

时间:2019-02-13 20:44:37

标签: javascript reactjs redux

在我的屏幕上,我有两列,左列是交易列表,右列显示了您在左侧列表中单击的最后一笔交易的详细信息。

响应Redux操作ONE_TRANS_LOAD_DETAILS填充详细信息

我使用html而不是React来生成左侧的列表。我想添加一个onClick事件,以分派type ='ONE_TRANS_LOAD_DETAILS'的动作。

如果左手列表也是rect组件,我可以这样做,但是在访问商店以调用store.dispatch({type:'ONE_TRANS_LOAD_DETAILS',transId:55});

在左侧的html列表中,我有<div class='row' onClick="store.dispatch({ type: 'ONE_TRANS_LOAD_DETAILS',transId: {{ $trans->id }} }))">(我使用带有刀片模板的laravel生成此html)

我已在我的应用程序根代码(footer.js)中将商店设置为导出:

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducer from './reducer';
import TransDetails from "./components/TransDetails";
export const store = createStore(reducer);
require('./components/Allocations.js');

if (document.getElementById('allocations')) {
    render(
        <Provider store={store}>
            <TransDetails />
        </Provider>,
        document.getElementById('allocations')
    );
}

那么如何确保将store设置为可用于左侧html列表的redux存储区?

我尝试过:

1)将导出​​内容放到webpack为我构建的名为“ money.js”的javascript文件中,然后导入html标头:<script src="js/money.js"></script> money.js:

require('./bootstrap');
import { store } from './footer.js';

但是当我尝试在html列表中使用它时,我得到“未定义存储”

2)因此,我尝试在正文中添加一个脚本标签:

</head>
<body>
<script>
import { store } from './footer.js';
</script>
...

但是我在导入{存储}行收到'SyntaxError:意外令牌{'

3)我尝试将导入放在首位:

<script>
import { store } from './footer.js';
</script>

但是我也会遇到意外的令牌错误。

4)(感谢@MTCoatser)我使accessStore由webpack处理以确保兼容性: 新的javascript文件storeAccess:

import reducer from './reducer';
import { createStore } from 'redux';
var store = createStore(reducer);

laravel组合中的新行(webpack包装器).react('resources/js/storeAccess.js','public/js')

并添加 <script src="js/storeAccess.js"></script> 到html头

从footer.js中删除了商店定义:

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import Allocations from "./components/Allocations";

require('./components/Allocations.js');

if (document.getElementById('allocations')) {
    render(
        <Provider store={store}>
            <Allocations />
        </Provider>,
        document.getElementById('allocations')
    );
}

并且由于此代码是在storeAccess.js之后加载的,因此无论如何该代码商店都应该可以使用。

并没有在html主体中的onClick =“ store.dispatch处定义获取商店。

但是在store.dispatch行仍然显示“未定义存储”。

实际上,如果我将console.log(store)放在头部,则它也是未定义的:

...
<script src="js/storeAccess.js"></script>
<script>console.log("In head",store)</script> <-- throws store is not defined
</head>

我希望这只是一个JavaScript范围或格式问题!救命!

1 个答案:

答案 0 :(得分:0)

我最终使用了全局窗口对象。在我的html中:

<div class='row transactionRow' onClick="window.storeGlobal.dispatch({type:'foo',payload:'bar'});"

并在storeAccess.js中定义window.storeGlobal:

storeAccess.js:

import { createStore } from 'redux';
window.storeGlobal = createStore(reducer);

storeAccess通过laravel混合打包 webpack.mix.js:

webpack.mix.js:

mix.react('resources/js/money.js', 'public/js')
   .react('resources/js/footer.js','public/js')
   .react('resources/js/storeAccess.js','public/js')
   .sass('resources/sass/money.scss', 'public/css');

我花了一段时间试图在stroeAccess.js中使用var store这样的语句导出export store;变量,但是我不知道如何以一种跨平台工作的方式导入它浏览器。上面的工作奏效了,所以我同意了。