我正在使用redux进行动态网格的状态管理,有人可以在其中添加自己的组件。我正在将此库用于网格 https://github.com/STRML/react-grid-layout.
我想使用 Gun 作为持久性层,用于将网格及其组件的当前状态存储和复制到用户配置文件中。 我的应用程序目前不使用 Express.js所以我在运行示例时遇到了一些问题,因为它们都使用 Express。我也在使用反应枪,但我无法弄清楚如何使用 Redux 商店提供商设置枪支提供商
是否有规范的方法/示例将 Gun 与 Redux 一起使用以进行 React?
我试过这个
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import Gun from 'gun';
import { GunProvider } from 'react-gun';
import App from './App';
import configureStore from './redux/store/configureStore';
import * as serviceWorker from './serviceWorker';
const gun = Gun({ file: 'db' });
ReactDOM.render(
<GunProvider gun={gun}>
<Provider store={configureStore()}>
<App />
</Provider>
</GunProvider>,
document.getElementById('root')
);
serviceWorker.unregister();
而这个
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import Gun from 'gun';
import { GunProvider } from 'react-gun';
import App from './App';
import configureStore from './redux/store/configureStore';
import * as serviceWorker from './serviceWorker';
const gun = Gun({ file: 'db' });
ReactDOM.render(
<Provider store={configureStore()}>
<GunProvider gun={gun}>
<App />
</GunProvider>
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
我没有看到构建或运行应用程序的任何错误
控制台日志启动
[HMR] Waiting for update signal from WDS...
gun.js:863 Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!
控制台日志显示我在上面的代码中记录的"data"变量
data: Gun
_:
$: Gun {_: {…}}
ack: 1
back: {gun: Gun, $: Gun, opt: {…}, root: {…}, graph: {…}, …}
get: "data"
gun: Gun {_: {…}}
id: 79
on: ƒ onto(tag, arg, as)
put: undefined
root: {gun: Gun, $: Gun, opt: {…}, root: {…}, graph: {…}, …}
soul: "data"
tag: {in: {…}, out: {…}}
__proto__: Object
__proto__: Object
但我没有看到Chrome>>"应用程序"标签页>>本地存储中出现任何内容
我在yarn build
日志中看到这个,但我不确定它是否相关
WARNING in ../node_modules/gun/gun.js 10:16-28
Critical dependency: the request of a dependency is an expression
@ ./index.jsx
这是我如何使用 yarn 构建/运行项目 包.json
"scripts": {
"start": "cross-env-shell NODE_ENV=development node --max-old-space-size=12288 node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode development --open",
"build": "cross-env-shell NODE_ENV=production node --max_old_space_size=12288 node_modules/webpack/bin/webpack.js --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
这是我如何在组件中使用枪
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { withGun } from 'react-gun';
import Logger from '../appLogger/logger';
const log = new Logger({
childType: 'component',
childName: 'Foo'
});
class Foo extends Component {
static propTypes = {
blah: PropTypes.string.isRequired
};
constructor(props) {
super(props);
}
componentDidMount() {
const data = this.props.gun.get('data').once(() => {});
log.debug({
msg: '[component] [componentDidMount] MainLayout',
methodType: 'componentDidMount',
logObjectName: 'data',
logObject: data
});
}
render() {
const { blah } = this.props;
return (
<div>
{blah}
</div>
);
}
}
export default withGun(Foo);
预期成果 -
我应该看到一个名为"枪"的条目 Chrome DevTools>> "应用程序"选项卡>> 本地存储
实际结果 -
我在本地存储>>Chrome Chrome DevTools>>"应用程序"选项卡中没有看到任何内容
预先披露:我是一个竞争库的开发人员,该库尚未退出测试版(可能会被重命名):https://github.com/rm-rf-etc/react-gun
您正在使用的react-gun
库对我来说似乎毫无意义。通过删除它,可以用更少的代码完成更多工作。
项目中的某个位置,包括:
// ./setup-gun.js
import Gun from 'gun/gun';
const gun = Gun();
export default gun.get('app_root');
正如我们在 gitter 上讨论的那样,我建议将你的枪支数据直接绑定到 react 组件,如下所示。但是,如果您必须使用 redux,请跳到 redux 示例。
用枪反应
在组件内部,使用钩子在数据进入时触发更新。喜欢这个:
// ./index.js
import React from 'react';
import node from './setup-gun.js';
export const Component = () => {
const ref = React.useRef(null);
const [count, setCount] = React.useState(0);
ref.current = count;
const increment = React.useCallback(() => setCount(ref.current + 1));
React.useEffect(() => {
node.get('count').on((val) => setCount(val));
// you will also need to capture and store a reference to `chain.off`
// inside of `.on` so you can call it when the component unmounts:
// return () => listeners.forEach(l => l.off())
}, []);
return (
<div>
<button onClick={increment}>Increment</button>
<div>{ref.current}</div>
</div>
);
};
如果要管理多个状态数据,可以将useState
替换为useReducer
。
枪与雷杜克斯
// ./gun-redux.js
import node from './setup-gun.js';
import { setCount } from './actions.js';
// export store after you configure it
import store from './store.js';
// trigger action from gun listener, will fire when count changes
node.get('count').on((val) => store.dispatch(setCount(val)));
// ./index.js
import React from 'react';
import node from './gun.js';
const countNode = node.get('count');
const increment = () => countNode.once((val) => countNode.put(val + 1));
const Component = ({ count }) => (
<div>
<button onClick={increment}>Increment</button>
<div>{count}</div>
</div>
);
const mapStateToProps = (state) => ({
count: state.count,
});
export default connect(mapStateToProps)(Component);
我认为前一种方法(没有 redux)不会那么令人困惑。使用 gun 会使 redux 变得毫无意义,因为您可以读取当前状态并直接从 gun 获取更新,因此使用 redux 会在框架中创建不必要的功能重复。
此示例假定你直接从 gun 中的应用根目录读取计数属性。显然,您需要执行更类似于const countNode = node.get(recordId).get('count');
的操作,其中recordId
是要绑定到的任何数据条目的字符串 ID。