{"_id":"react-hook-module","_rev":"29-3a1b6e7951b880c66a8fb9827e6ad697","time":{"0.3.2":"2020-12-08T15:27:32.428Z","created":"2020-12-09T17:45:46.488Z","0.3.5":"2020-12-09T17:45:46.696Z","modified":"2022-05-14T12:10:17.877Z"},"name":"react-hook-module","dist-tags":{"latest":"0.3.5"},"versions":{"0.3.5":{"name":"react-hook-module","version":"0.3.5","description":"A react module hook for real configurable app with stateful persistent module tree and peer-to-peer messaging mechanism","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","pub":"npm run build && npm publish"},"repository":{"type":"git","url":"git+https://github.com/linb/react-module-hook.git"},"keywords":["react","configurable","stateful","predictable","messaging","react-hook-form","react-router","axios","hotkeys-js","material-ui"],"author":{"name":"linb"},"license":"MIT","bugs":{"url":"https://github.com/linb/react-module-hook/issues"},"homepage":"https://github.com/linb/react-module-hook#readme","dependencies":{"react":"17.0.0","react-dom":"17.0.0"},"devDependencies":{},"_id":"react-hook-module@0.3.5","_nodeVersion":"12.18.3","_npmVersion":"6.14.7","dist":{"integrity":"sha512-EM5zEFgt8UJHaLYzx2AH6l7teJ2PXY+oigr43Po8+vyKXJqCnuSA0ytYGd4e314sehUFltgXbSSvA1eAZkiGng==","shasum":"746fce9ce31ec25f1a4e5d4fbc9ae84bde9947d6","tarball":"https://registry.npmjs.org/react-hook-module/-/react-hook-module-0.3.5.tgz","fileCount":9,"unpackedSize":116464,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0Q1LCRA9TVsSAnZWagAAwmAP/RkoKXOxkZ8WYyb8aFMG\n2Qfl24KH/J7IKnkjQ01aO/EFt0yBq7QEwIlVS1WwP5PFUrlgG7My+n0GQ+Rv\nRG7DuQvVt7vpcwBS4WUBk3qExok9X1Z2r/HDzEtSlSSxD5yaoxdQEY0vuo/6\nbkXHUdlTkb2cY98IDesULCTq8blyli8IqKVubVODhR53HNtnoNDlWSuaHGp+\nkbMJ5iJWEy1XtJtkEe1t5R0TZ0AOYKmkTVIPGB/YSKOcw10D1/hPmiv7iWik\n+u5eL2TKuggOiskw4y68xVJeNV/IjSq1PM+QwplZGWu4uqf+ybFwuF7DPcP/\nkoQ2n5Q2FAzVKcNwGOmCk0h3zpN/FIPyaT3hd8iFEp5MNsnCewz3XYfc7KnF\n0rs4anXypSxHYuXqpCzB33VKirSNKFraS0m7RWCGz3uLi9SUN7Bc+OwhehMy\ncy2Z0HMRhwMMJLEEkenUd+pWpptDI6AKmqV1QR8ELfi9lrIszlmcwM7BLLJi\n5lES2Va6bwxLo2cIeZp9GecWrUlgnjeIadE7z62APBY2uCC0l3kXEB36YY7k\nPp505Ez1GZlJ8H/4Ux8N3IpBCFg+mikg4Mi5XlwXASQpzwQMRY/WazVaAaoL\n/Zp6Lu+1qisog2zqFipRCCWss7jTrkwQ+EaHuxsc8WuLGcy+wAEQp05FA8vd\n0a3+\r\n=Hsdz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDKNVqbGbW81zz5wpWHZKR9wzF4veGhbNwOE76W2T0DFwIhAMx8m7YE5EGf/ABgnVB0y2Wj2QtmrcI+JrRnyOWl3AfU"}]},"_npmUser":{"name":"linb818","email":"linb.net@gmail.com"},"directories":{},"maintainers":[{"name":"linb818","email":"linb.net@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-hook-module_0.3.5_1607535946531_0.4185032083469551"},"_hasShrinkwrap":false}},"maintainers":[{"name":"linb818","email":"linb.net@gmail.com"}],"description":"A react module hook for real configurable app with stateful persistent module tree and peer-to-peer messaging mechanism","homepage":"https://github.com/linb/react-module-hook#readme","keywords":["react","configurable","stateful","predictable","messaging","react-hook-form","react-router","axios","hotkeys-js","material-ui"],"repository":{"type":"git","url":"git+https://github.com/linb/react-module-hook.git"},"author":{"name":"linb"},"bugs":{"url":"https://github.com/linb/react-module-hook/issues"},"license":"MIT","readme":"# react-hook-module - version 0.3\r\nA react module hook for real configurable app with stateful persistent module tree and peer-to-peer messaging mechanism\r\n\r\n## 1. Usage\r\n### 1.1. Install\r\n```javascript\r\nnpm install react-hook-module\r\n```\r\n\r\n### 1.2. Import\r\n```javascript\r\nimport { useModule } from \"react-hook-module\";\r\n```\r\n### 1.3. Call it in a render function\r\n```javascript\r\n...\r\nconst ReactComponent = props => {\r\n  const { module, auth, router, request } = useModule(props, {\r\n    // the default state for this module\r\n    state:{},\r\n    // the default props for this module\r\n    props:{\r\n        // enable HotKeys\r\n        enableHotKeys: true,\r\n        // enable router\r\n        enableRouter: true,\r\n        // enable auth\r\n        enableAuth: true,\r\n        // the request configure\r\n        enableRequest: true,\r\n        req_url : `${useModule.resolveURL( \"data/demo.json\" ) }`,\r\n        req_data : { key : \"value\" },\r\n        req_method : \"post\",\r\n        req_baseURL : null,\r\n        req_AUTH_TOKEN : null,\r\n        req_header : null,\r\n        req_config : null,\r\n        req_execute : true\r\n    },\r\n    // actions for this module\r\n    actions:{\"actionName\":()=>()},\r\n    // for extra data\r\n    tagVar:{}    \r\n  }); \r\n\r\n  // ...\r\n  // return JSX;\r\n};\r\n```\r\n### 1.4. Use the component\r\n```javascript\r\n...\r\nconst ReactComSub1 = props => {\r\n  const { module } = useModule(props, { }); \r\n  return (\r\n    <div>\r\n      ReactComSub1\r\n    </div>\r\n  );\r\n};\r\nconst ReactComSub2 = props => {\r\n  const { module } = useModule(props, { }); \r\n  return (\r\n    <div>\r\n      ReactComSub2 - {props.name}\r\n    </div>\r\n  );\r\n};\r\nconst ReactCom = props => {\r\n  const { module } = useModule(props, {\r\n    state:{\r\n      items:[{\"name\":\"v1\"},{\"name\":\"v2\"}]\r\n    }\r\n  }); \r\n  const XReactComSub2 = module.enhanceCom(ReactComSub2);\r\n  return (\r\n    <div>\r\n      <ReactComSub1 usemodule_alias=\"alias1\" usemodule_uid=\"uid1\" usemodule_parent={module}/>\r\n      <ReactComSub2 usemodule_alias=\"alias2\" usemodule_uid=\"uid2\" usemodule_parent={module}/>\r\n      <XReactComSub2 usemodule_alias=\"alias3\" usemodule_uid=\"uid3\" x_id=\"x_id1\" x_iterator={module.state.items}/>\r\n    </div>\r\n  );\r\n};\r\n```\r\n```\r\n[root]\r\n  │  \r\n  └─<ReactCom >\r\n         │  \r\n         ├<ReactComSub1 usemodule_alias=\"alias1\">\r\n         │  \r\n         ├<ReactComSub2 usemodule_alias=\"alias2\">\r\n         │  \r\n         └<XReactComSub2 usemodule_uid=\"alias3\" x_id=\"x_id1\">\r\n```\r\n\r\n## 2. API \r\n### 2.1. useModule static functions\r\n#### `useModule.getRootModule`\r\n----\r\n> **useModule.getRootModule( )**  \r\n> &emsp;&emsp;*Gets the root useModule element.*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The root useModule element.*  \r\n```javascript\r\n  // to get the root useModule element\r\n  const rootModule = useModule.getRootModule();\r\n```\r\n#### `useModule.getModule`\r\n----\r\n> **useModule.getModule ( idOrAlias )**  \r\n> &emsp;&emsp;*Gets the useModule element by uid (usemodule_uid) or alias (usemodule_alias). Getting from alias is only for the child elements in the root useModule element )*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The result useModule element*  \r\n> **[parameters]**  \r\n> * **idOrAlias** [required] : *String, The target useModule element's uid or alias*  \r\n```javascript\r\n  // to get an useModule element with usemodule_uid=\"global_uid1\"\r\n  const module1 = useModule.getModule(\"global_uid1\");\r\n  // to get an useModule element (It's a child element in the root useModule element) with usemodule_alias=\"alias1\"\r\n  const module2 = useModule.getModule(\"alias1\");\r\n  // to get an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const module3 = useModule.getModule(\"alias_in_root.alias_in_level1.alias_in_level2\");  \r\n```\r\n#### `useModule.sendMessageTo`\r\n----\r\n> **useModule.sendMessageTo ( receiver, message )**  \r\n> &emsp;&emsp;*Sends a message to the target useModule element, which can  be received in it's onMessage event*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The return value of target useModule element's onMessage event*  \r\n> **[parameters]**  \r\n> * **receiver** [required] : *String or Object, The target useModule element, which can be an useModule object, useModule uid or alias (if it's a child  element in the root useModule element ).*  \r\n> * **message** [required] : *Object / Any, The message, can be any value* \r\n```javascript\r\n  // to sent a message to module1\r\n  const result1 = useModule.sendMessageTo(module1, \"message\");\r\n  // to sent a message to an useModule element with usemodule_uid=\"global_uid1\"\r\n  const resul2 = useModule.sendMessageTo(\"global_uid1\", \"message\");\r\n  // to sent a message to an useModule element ( a child element in the root useModule element) with usemodule_alias=\"alias1\"\r\n  const resul3 = useModule.sendMessageTo(\"alias1\", \"message\");\r\n  // to sent a message to an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const resul4 = useModule.sendMessageTo(\"alias_in_root.alias_in_level1.alias_in_level2\", \"message\");  \r\n```\r\n\r\n#### `useModule.dispatchActionTo`\r\n----\r\n> **useModule.dispatchActionTo ( receiver, actionName, params, from)**  \r\n> &emsp;&emsp;*Dispatches an action of the target useModule element*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The target action's return value*  \r\n> **[parameters]**  \r\n> * **receiver** [required] : *String or Object, The target useModule, which can be an useModule object, useModule uid or alias (only for those child elements in the root useModule element ).*  \r\n> * **actionName** [required] : *String, The action name to be dispatched* \r\n> * **params** [optional] : *Array, The parameters for the given action* \r\n> * **from** [optional] : *Object/Any, The from info that indicates who dispatch the action or can be other info* \r\n```javascript\r\n  // to dispatch an action of module1\r\n  const result1 = useModule.dispatchActionTo(module1, \"actionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element with usemodule_uid=\"global_uid1\"\r\n  const resul2 = useModule.dispatchActionTo(\"global_uid1\", \"actionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element (a child element in the root useModule element) with usemodule_alias=\"alias1\"\r\n  const resul3 = useModule.dispatchActionTo(\"alias1\", \"actionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const resul4 = useModule.dispatchActionTo(\"alias_in_root.alias_in_level1.alias_in_level2\", \"actionName\", [/*parameters*/]);\r\n```\r\n#### `useModule.dispatchAsyncActionTo`\r\n----\r\n> **useModule.dispatchAsyncActionTo ( receiver, actionName, params, from)**  \r\n> &emsp;&emsp;*Dispatches an asynchronous action of the target useModule element*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The target action's return value*  \r\n> **[parameters]**  \r\n> * **receiver** [required] : *String or Object, The target useModule, which can be an useModule object, useModule uid or alias (only for the child elements in the root useModule element ).*  \r\n> * **actionName** [required] : *String, The asynchronous action name to be dispatched* \r\n> * **params** [optional] : *Array, The parameters for the given action* \r\n> * **from** [optional] : *Object/Any, The from info that indicates who dispatch the action or can be other info* \r\n```javascript\r\n  // to dispatch an action of module1, \r\n  const result1 = useModule.dispatchAsyncActionTo(module1, \"asyncActionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element with usemodule_uid=\"global_uid1\"\r\n  const resul2 = useModule.dispatchAsyncActionTo(\"global_uid1\", \"asyncActionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element (a child elemnt in the root useModule element) with usemodule_alias=\"alias1\"\r\n  const resul3 = useModule.dispatchAsyncActionTo(\"alias1\", \"asyncActionName\", [/*parameters*/]);\r\n  // to dispatch an action of an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const resul4 = useModule.dispatchAsyncActionTo(\"alias_in_root.alias_in_level1.alias_in_level2\", \"asyncActionName\", [/*parameters*/]);\r\n```\r\n#### `useModule.updateStateFor`\r\n----\r\n> **useModule.updateStateFor ( target, path, state, force )**  \r\n> &emsp;&emsp;*Updates the module state for the target useModule element*  \r\n> **[parameters]**  \r\n> * **target** [required] : *String or Object, The target useModule element, which can be an useModule element object, useModule uid or alias (only for those chlid elements in the root useModule element ).*  \r\n> * **path** [required] : *Object / Array< String > / String, **If it's an Array< String >: to** specify the path for updating the state; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'; **If it's an Object**: to specify the whole object to update the state, the 2nd parameter - 'state' will be ignored in this case.* \r\n> * **state** [optional] : *Object, The object to update the state in the given path* \r\n> * **force** [optional] : *Boolean, Indicates whether force to update the state. Default is false.* \r\n```javascript\r\n  // to update state for module1\r\n  useModule.updateStateFor(module1, { key:\"value\" });\r\n  // to update state for an useModule element with usemodule_uid=\"global_uid1\"\r\n  useModule.updateStateFor(\"global_uid1\", \"key\", \"value\");\r\n  // to update state for an useModule element (a child element in the root useModule element) with usemodule_alias=\"alias1\"\r\n  useModule.updateStateFor(\"alias1\", \"keylevel1.keylevel2.keylevel3\", \"value\");\r\n  // to update state for an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  useModule.updateStateFor(\"alias_in_root.alias_in_level1.alias_in_level2\", \"key\", \"value\");\r\n```\r\n#### `useModule.fireEventTo`\r\n ----\r\n> **useModule.fireEventTo ( target, eventName, params, from)**  \r\n> &emsp;&emsp;*Fires an event of the target useModule element*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, The return value of the target event*  \r\n> **[parameters]**  \r\n> * **target** [required] : *String or Object, The target useModule element, which can be an useModule element object, useModule uid or alias ( only for those child elements in the root useModule element ).*  \r\n> * **eventName** [required] : *String, The event name* \r\n> * **params** [optional] : *Array, The parameters for the given event* \r\n> * **from** [optional] : *Object/Any, The from info that indicates who fire the event  or can be other info* \r\n```javascript\r\n  // to fire an event for module1\r\n  const result1 = useModule.fireEventFor(module1, \"eventName\", [/*parameters*/]);\r\n  // to fire an event for an useModule element with usemodule_uid=\"global_uid1\"\r\n  const resul2 = useModule.fireEventFor(\"global_uid1\", \"eventName\", [/*parameters*/]);\r\n  // to fire an event for an useModule element (a child element in the root useModule element) with usemodule_alias=\"alias1\"\r\n  const resul3 = useModule.fireEventFor(\"alias1\", \"eventName\", [/*parameters*/]);\r\n  // to fire an evnt for an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const resul4 = useModule.fireEventFor(\"alias_in_root.alias_in_level1.alias_in_level2\", \"eventName\", [/*parameters*/]);\r\n```\r\n#### `useModule.broadcast`\r\n ----\r\n> **useModule.broadcast ( channelName, message)**  \r\n> &emsp;&emsp;*Broadcasts message to all useModule elements via a specified channel, which can be received in all useModule elements' onChannelMessage event*  \r\n> **[parameters]**  \r\n> * **channelName** [required] : *String, The channel name*  \r\n> * **message** [required] : *Object / Any, The message object, can be any value* \r\n```javascript\r\n  // to broadcast an message to all useModule elements\r\n  useModule.broadcast(\"channelName\",\"message\");\r\n```\r\n#### `useModule.printModulesTree`\r\n ----\r\n> **useModule.printModulesTree ( )**  \r\n> &emsp;&emsp;*Prints the useModule element tree to the console window*  \r\n```javascript\r\n  // to print the whole useModule element tree onto the console\r\n  useModule.printModulesTree( );\r\n```\r\n#### `useModule.resolveURL`\r\n----\r\n> **useModule.resolveURL ( relPath )**  \r\n> &emsp;&emsp;*Resolves an url from a relative path. If you want to use a relative resource path in the CrossUI Designer, it's a must*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The resolved url*  \r\n> **[parameters]**  \r\n> * **relPath** [required] : *String, The relative path for an url* \r\n```javascript\r\n  // to resolve a relative path for the resource url\r\n  useModule.resolveURL(\"./img/pic.png\");\r\n```\r\n#### `useModule.getDataFromStore`\r\n ----\r\n> **useModule.getDataFromStore ( path )**  \r\n> &emsp;&emsp;*Gets data from the global store by the path*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, The result data*  \r\n> **[parameters]**  \r\n> * **path** [required] : *Array< String > /  String, **If it's an Array< String >**: to specify the path for the data; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'* \r\n#### `useModule.setDataToStore`\r\n ----\r\n> **useModule.setDataToStore ( path, value, clonePath )**  \r\n> &emsp;&emsp;*Sets data to the global store by the path*    \r\n> **[parameters]**  \r\n> * **path** [required] : *Array< String > /  String, **If it's an Array< String >**: to specify the path for the data; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'* \r\n> * **value** [required] : *Object / Any, The object to set* \r\n>  * **clonePath** [optional] : *Boolean,  Determines whether to clone the path or not. Default is false.* \r\n```javascript\r\n  // to get data from the global store\r\n  useModule.setDataToStore(\"path_level1.path_level2\", {data:\"value\"}, false);\r\n  // reusult: \"value\"\r\n  useModule.getDataFromStore(\"path_level1.path_level2.data\");\r\n```\r\n### 2.2. useModule utils functions\r\n#### `useModule.utils.getRand`\r\n ----\r\n> **useModule.utils.getRand ( preTag )**  \r\n> &emsp;&emsp;*Gets a random string. The result like 'ca1gis'.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The random string.*  \r\n> **[parameters]**  \r\n> * **preTag** [optional] : *String, The previous tag for the random string. Default is empty string.* \r\n```javascript\r\n  // The result like 'ca1gis\r\n  useModule.getRand();\r\n  // The result like 'id_ca1gis'\r\n  useModule.getRand(\"id_\");\r\n```\r\n#### `useModule.utils.getNo`\r\n ----\r\n> **useModule.utils.getNo ( preTag )**  \r\n> &emsp;&emsp;*Gets a No. string. The result like 'a'.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The No. string.*  \r\n> **[parameters]**  \r\n> * **preTag** [optional] : *String, The previous tag for the No. string. Default is empty string.* \r\n```javascript\r\n  // The result like 'a'\r\n  useModule.utils.getNo();\r\n  // The result like 'id_a'\r\n  useModule.utils.getNo(\"id_\");\r\n```\r\n#### `useModule.utils.deepGet`\r\n ----\r\n> **useModule.utils.deepGet ( object, path )**  \r\n> &emsp;&emsp;*Gets data from the given object by the path.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object/Any, The result data.*  \r\n> **[parameters]**  \r\n> * **object** [required] : *Object, The target object.* \r\n> * **path** [required] : *Array< String > / String, The path. **If it's an Array< String >**: to specify the path for the data; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'* \r\n```javascript\r\n  // return 1\r\n  useModule.utils.deepGet({a:{b:{c:1}}},'a.b.c');\r\n  // return 1\r\n  useModule.utils.deepGet({a:{b:{c:1}}},[\"a\",\"b\",\"c\"]);\r\n```\r\n#### `useModule.utils.deepSet`\r\n ----\r\n> **useModule.utils.deepSet ( object, path )**  \r\n> &emsp;&emsp;*Sets data to the given object by the path.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object/Any, The target object.*  \r\n> **[parameters]**  \r\n> * **object** [required] : *Object, The target object.* \r\n> * **path** [required] : *Array< String > / String, The path. **If it's an Array< String >**: to specify the path for the data; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'* \r\n> * **value** [required] : *Object/Any, The value to set.*  \r\n> * **clonePath** [optional] : *Boolean, Determines whether to clone the path or not. Default is false.*  \r\n```javascript\r\n  // result : {a:{b:{c:2}}}\r\n  useModule.utils.deepSet({a:{b:{c:1}}},'a.b.c', 2);\r\n  // result : {a:{b:{c:[1,2,3]}}}\r\n  useModule.utils.deepSet({a:{b:{c:1}}},[\"a\",\"b\",\"c\"], [1,2,3]);\r\n```\r\n#### `useModule.utils.deepClone`\r\n ----\r\n> **useModule.utils.deepClone ( object )**  \r\n> &emsp;&emsp;*Clones the given object deeply.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object/Any, The cloned object.*  \r\n> **[parameters]**  \r\n> * **object** [required] : *Object, The target object to be cloned.*\r\n```javascript\r\n  const source = {a:{b:{c:1}}};\r\n  // cloned : {a:{b:{c:1}}}\r\n  // cloned.a === source.a      > false\r\n  // cloned.a.b === source.a.b  > false\r\n  const cloned = useModule.utils.deepClone(source);\r\n```\r\n#### `useModule.utils.toUTF8`\r\n ----\r\n> **useModule.utils.toUTF8 ( source )**  \r\n> &emsp;&emsp;*Converts a string to UTF-8 string.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The result UTF-8 string .*  \r\n> **[parameters]**  \r\n> * **utf8string** [required] : *String, The target string to be converted.*\r\n#### `useModule.utils.fromUTF8`\r\n ----\r\n> **useModule.utils.fromUTF8 ( utf8string )**  \r\n> &emsp;&emsp;*Converts an UTF-8 string back.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The result string .*  \r\n> **[parameters]**  \r\n> * **utf8string** [required] : *String, The target UTF-8 string to be converted.*\r\n```javascript\r\n  const source = '漢字';\r\n  // \"\\u6f22\\u5b57\"\r\n  const utf8 = useModule.utils.toUTF8(source);\r\n  // source === back\r\n  const back = useModule.utils.fromUTF8(utf8 );\r\n  console.log(utf8, back);\r\n```\r\n#### `useModule.utils.makeURLQueryString`\r\n ----\r\n> **useModule.utils.makeURLQueryString ( hash )**  \r\n> &emsp;&emsp;*Converts an object into an url query string.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The result query string.*  \r\n> **[parameters]**  \r\n> * **hash** [required] : *Object, The target object to be converted.*\r\n#### `useModule.utils.getURLParams`\r\n ----\r\n> **useModule.utils.getURLParams ( querystring )**  \r\n> &emsp;&emsp;*Converts an object into an url query string.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, The result query string.*  \r\n> **[parameters]**  \r\n> * **querystring** [required] : *Object, The target querystring.*\r\n> * **parameter** [optional] : *String, The parameter key string. If don't specify this, it will return an object that presents all parameters.*\r\n```javascript\r\n  const hash = {k1:\"v1\",k2:\"v2\"};\r\n  // return \"k1=v1&k2=v2\"\r\n  const qs= useModule.utils.makeURLQueryString(hash);\r\n  // return {k1:\"v1\",k2:\"v2\"}\r\n  const back = useModule.utils.getURLParams(utf8 );\r\n  // return \"v2\"\r\n  const value = useModule.utils.getURLParams(utf8, \"k2\" );\r\n  console.log(qs, back, value );\r\n```\r\n#### `useModule.utils.getCookie`\r\n ----\r\n> **useModule.utils.getCookie ( name )**  \r\n> &emsp;&emsp;*Gets a specified cookie with the given name.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String/Object/Array, The result cookie for the given name. If it's a stringified object or array, it will return the original object or array.*  \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The cookie name.*\r\n#### `useModule.utils.setCookie`\r\n ----\r\n> **useModule.utils.setCookie ( name, value, options )**  \r\n> &emsp;&emsp;*Creates a cookie with the given name, value, and options.*    \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The cookie name.*\r\n> * **value** [required] : *String/Object/Array, The value of cookie. If it's an Object or Array, a stringified string will be saved into Cookie.*\r\n> * **options** [options] : *Object, The cookie options. { expires: Number for seconds, path: String, domain: String, maxAge: String, sameSite: Boolean, secure: Boolean, httpOnly: Boolean }.*\r\n#### `useModule.utils.removeCookie`\r\n ----\r\n> **useModule.utils.removeCookie ( name )**  \r\n> &emsp;&emsp;*Removes a specified cookie by the given name.*    \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The cookie name.*\r\n#### `useModule.utils.clearCookie`\r\n ----\r\n> **useModule.utils.clearCookie ( )**  \r\n> &emsp;&emsp;*Clears all cookies.*    \r\n```javascript\r\n  useModule.utils.setCookie(\"c1\", \"v1\");\r\n  useModule.utils.setCookie(\"c2\", {k1:\"v1\",k2:\"v2\"});\r\n  // return \"v1\"\r\n  const cookie1 = useModule.utils.getCookie( \"c1\" );\r\n  // return {k1:\"v1\",k2:\"v2\"}\r\n  const cookie2 = useModule.utils.getCookie( \"c2\" );\r\n  console.log( cookie1, cookie2 );\r\n  useModule.utils.removeCookie( \"c1\" );\r\n  useModule.utils.clearCookie( );\r\n```\r\n#### `useModule.utils.getLocalStorage`\r\n ----\r\n> **useModule.utils.getLocalStorage ( name )**  \r\n> &emsp;&emsp;*Gets a specified local storage by the given name.*    \r\n>  **[return]**  \r\n> &emsp;&emsp;*String/Object/Array, The result local storage for the given name. If it's a stringified object or array, it will return the original object or array.*  \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The local storage name.*\r\n#### `useModule.utils.setLocalStorage`\r\n ----\r\n> **useModule.utils.setLocalStorage ( name, value )**  \r\n> &emsp;&emsp;*Creates a local storage data with the given name and value.*    \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The local storage name.*\r\n> * **value** [required] : *String/Object/Array, The value of local storage. If it's an Object or Array, a stringified string will be saved into local storage.*\r\n#### `useModule.utils.removeLocalStorage`\r\n ----\r\n> **useModule.utils.removeLocalStorage ( name )**  \r\n> &emsp;&emsp;*Removes a specified local storage by the given name.*    \r\n> **[parameters]**  \r\n> * **name** [required] : *String, The local storage name.*\r\n#### `useModule.utils.clearLocalStorage`\r\n ----\r\n> **useModule.utils.clearLocalStorage (  )**  \r\n> &emsp;&emsp;*Clears all local storage.*    \r\n```javascript\r\n  useModule.utils.setLocalStorage (\"c1\", \"v1\");\r\n  useModule.utils.setLocalStorage (\"c2\", {k1:\"v1\",k2:\"v2\"});\r\n  // return \"v1\"\r\n  const sto1 = useModule.utils.getLocalStorage( \"c1\" );\r\n  // return {k1:\"v1\",k2:\"v2\"}\r\n  const sto2 = useModule.utils.getLocalStorage( \"c2\" );\r\n  console.log( sto1, sto2 );\r\n  useModule.utils.removeLocalStorage( \"c1\" );\r\n  useModule.utils.clearLocalStorage( );\r\n```\r\n#### `useModule.utils.postH5ChannelMessage`\r\n ----\r\n> **useModule.utils.postH5ChannelMessage ( channelName, message)**  \r\n> &emsp;&emsp;*Posts HTML5 message ( ref: window.BroadcastChannel ) to all browser windows via a specified channel, which can be received in all useModule components' onH5ChannelMessage event*  \r\n> **[parameters]**  \r\n> * **channelName** [required] : *String, The channel name*  \r\n> * **message** [required] : *Object / Any, The message object, can be any value* \r\n```javascript\r\n  // to pose HTML5 message to all browser windows via \"channel1\"\r\n  useModule.utils.postH5ChannelMessage (\"channel1\",\"message\");\r\n```\r\n#### `useModule.utils.selectLocalFiles`\r\n ----\r\n> **useModule.utils.selectLocalFiles ( contentType, multiple )**  \r\n> &emsp;&emsp;*To show an browser's file dialog for selecting files. You must use 'await' to call it, and it must be in an async function.*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Array < File >, The result files.*  \r\n> **[parameters]**  \r\n> * **contentType** [optional] : *String, The content type. e.g. 'image/png', 'image/\\*'*  \r\n> * **multiple** [optional] : *Boolean, Allows multiple files or not. Default is false* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  //...\r\n  const App = props => {\r\n      const { module } = useModule(props, { }); \r\n      return (\r\n        <div>\r\n          <button onClick={async () => {\r\n            const files = await useModule.utils.selectLocalFiles(\"image/*\", true);\r\n            console.log(files);\r\n          }}>module.request</button>\r\n        </div>\r\n      );\r\n  };\r\n```\r\n### 2.3. useModule instance - module functions\r\n#### `getRootModule`\r\n----\r\n> **getRootModule ( )**  \r\n> &emsp;&emsp;*Gets the root useModule element*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The root useModule element*  \r\n```javascript\r\n  // to get the root useModule element\r\n  const rootModule = module.getRootModule();\r\n```\r\n#### `getModule`\r\n----\r\n> **getModule ( idOrAlias )**  \r\n> &emsp;&emsp;*Gets the useModule element by uid (usemodule_uid) or alias (usemodule_alias). Getting from alias is only for the child elements in the root useModule element )*    \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The result module element*  \r\n> **[parameters]**  \r\n> * **idOrAlias** [required] : *String, The target useModule element's uid or alias*  \r\n```javascript\r\n  // to get an useModule element with usemodule_uid=\"global_uid1\"\r\n  const module1 = module.getModule(\"global_uid1\");\r\n  // to get an useModule element( a child element in the current module) with usemodule_alias=\"alias1\"\r\n  const module2 = module.getModule(\"alias1\");\r\n  // to get an useModule element with alias path: [\"alias_in_root\", \"alias_in_level1\", \"alias_in_level2\"]\r\n  const module3 = module.getModule(\"alias_in_root.alias_in_level1.alias_in_level2\");  \r\n```\r\n#### getModuleByAlias\r\n ----\r\n> **getModuleByAlias ( alias )**  \r\n> &emsp;&emsp;*Gets a useModule  element by the given alias in the current module, which must be a child element in the current module and has an alias (usemodule_alias property)*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The result module element*  \r\n> **[parameters]**  \r\n> * **alias** [required] : *String, The alias of the element* \r\n```javascript\r\n  // to get a child module in the current module with usemodule_alias=\"alias1\"\r\n  const childModule = module.getModuleByAlias(\"alias1\");\r\n```\r\n#### `sendMessage`\r\n----\r\n> **sendMessage ( message )**  \r\n> &emsp;&emsp;*Sends a message to the current useModule, which can  be received in it's onMessage event*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The return value of the module's onMessage event*  \r\n> **[parameters]**  \r\n> * **message** [required] : *Object / Any, The message object, can be any value* \r\n```javascript\r\n  // to sent a message\r\n  const result1 = module.sendMessage(\"message\");  \r\n```\r\n#### `dispatchAction`\r\n----\r\n> **dispatchAction ( actionName, params, from )**  \r\n> &emsp;&emsp;*Dispatches an action for the current useModule element*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The target action's return value*  \r\n> **[parameters]**  \r\n> * **actionName** [required] : *String, The action name to be dispatched* \r\n> * **params** [optional] : *Array, The parameters for the given action* \r\n> * **from** [optional] : *Object/Any, The from info that indicates who dispatch the action or can be other info* \r\n```javascript\r\n  // to dispatch an action\r\n  const result1 = module.dispatchAction(\"actionName\", [/*parameters*/]);\r\n```\r\n#### `dispatchAsyncAction`\r\n----\r\n> **dispatchAsyncAction ( actionName, params, from)**  \r\n> &emsp;&emsp;*Dispatches an asynchronous action for the current useModule element*  \r\n> **[return]**  \r\n> &emsp;&emsp;*Object, The target action's return value*  \r\n> **[parameters]**  \r\n> * **actionName** [required] : *String, The asynchronous action name to be dispatched* \r\n> * **params** [optional] : *Array, The parameters for the given action* \r\n> * **from** [optional] : *Object/Any, The from info that indicates who dispatch the action or can be other info* \r\n```javascript\r\n  // to dispatch an async action\r\n  const result1 = module.dispatchAsyncAction(\"asyncActionName\", [/*parameters*/]);\r\n``` \r\n#### `updateState`\r\n----\r\n> **updateState ( path, state, force )**  \r\n> &emsp;&emsp;*Updates the module state for the current useModule*  \r\n> **[parameters]**  \r\n> * **path** [required] : *Object / Array< String > / String, **If it's an Array< String >: ** to specify the path for updating the state; **If it's a String**: the string can be convert into an Array< String > after splitting by '.'; **If it's an Object**: to specify the whole object to update the state, the 2nd parameter - 'state' will be ignored  in this case.* \r\n> * **state** [optional] : *Object/Any, The object to update the state in the given path* \r\n> * **force** [optional] : *Boolean, Indicates whether force to update the state. Default is false.*\r\n```javascript\r\n  // If the old state is {key:'ovalue',key1:{key2:'ovalue'}}\r\n  // the new state will be {key:'nvalue',key1:{key2:'ovalue'}}\r\n  module.updateState({ \"key\":\"nvalue\" });\r\n  // the new state will be {key:'nvalue',key1:{key2:'nvalue'}}\r\n  module.updateState(\"key1,key2\", \"nvalue\");\r\n```\r\n#### `fireEvent`\r\n----\r\n> **fireEvent ( eventName, params, from  )**  \r\n> &emsp;&emsp;*Fires a specified event for the current useModule*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, The return value of the target event*  \r\n> **[parameters]**  \r\n> * **eventName** [required] : *String, The event name* \r\n> * **params** [optional] : *Array, The parameters for the given event* \r\n> * **from** [optional] : *Object/Any, The from info that indicate who fire the event or can be other info* \r\n```javascript\r\n  // to fire an event \r\n  const result1 = module.fireEvent(\"eventName\", [/*parameters*/]);\r\n```\r\n#### `broadcast`\r\n ----\r\n> **broadcast ( channelName, message )**  \r\n> &emsp;&emsp;*Broadcasts message to all useModule elements via a specified channel, which can be received in all useModule components' onChannelMessage event.*  \r\n> **[parameters]**  \r\n> * **channelName** [required] : *String, The channel name*  \r\n> * **message** [required] : *Object / Any, The message object, can be any value* \r\n```javascript\r\n  // to broadcast an message to all useModule elements\r\n  useModule.broadcast(\"channelName\",\"message\");\r\n```\r\n#### `useRef`\r\n ----\r\n> **useRef ( refName, value )**  \r\n> &emsp;&emsp;*Triggers a React.useRef to create a ref, which initialial value is 'value'. It can be retrieved by module.getRef('refName') .*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, The ref*  \r\n> **[parameters]**  \r\n> * **refName** [required] : *String, The ref name* \r\n> * **value** [optional] : *Object/Any, The given initialial value* \r\n#### `getRef`\r\n ----\r\n> **getRef ( refName )**  \r\n> &emsp;&emsp;*Gets a specified ref by the given name, this ref was created by module.useRef('refName', 'value').*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, The ref*  \r\n> **[parameters]**  \r\n> * **refName** [required] : *String, The ref name* \r\n```javascript\r\n  // to use(create) a ref\r\n  const ref = module.useRef(\"refName\", \"init vaule\");\r\n  // to get the ref\r\n  const ref1 = module.getRef(\"refName\");  \r\n  // or\r\n  const ref2 = module.refs[\"refName\"];\r\n```\r\n#### `renderComAs`\r\n ----\r\n> **renderComAs ( x_id, replace, beforeNodes, afterNodes )**  \r\n> &emsp;&emsp;*Renders an enhanced component (with a specified 'x_id') as a different  component or a set of components, which can be used as element replacement, or inserting additional elements before or after the element.*  \r\n> **[parameters]**  \r\n> * **x_id** [required] : *String, The target element's x_id. The target element must be an enhanced component which powered by module.enhanceCom()* \r\n> * **replace** [optional] : *Object/Array/false,  A React element or React elements array, which will replace the current element in the UI. If specified [false], this parameter will be ignored. If specified [null], the original element will be restored. Default is null.* \r\n> * **beforeNodes** [optional] : *Object/Array/false,  A React element or React elements array, which will be inserted before the current element. If specified [false], this parameter will be ignored. If specified [null], all beforeNodes will be removed. Default is null.* \r\n> * **afterNodes** [optional] : *Object/Array/false,  A React element or React elements array, which will be inserted after the current element. If specified [false], this parameter will be ignored. If specified [null], all afterNodes will be removed. Default is null.* \r\n```javascript\r\n  const Com1= props => {\r\n\t  const { module } = useModule(props, { });\r\n\t  const XElem = module.enchanceCom(\"div\");\r\n\t  return (\r\n\t  <div>\r\n\t\t  <XElem x_id=\"x_id1\">original</XElem>\r\n\t\t  <button onClick={() =>{\r\n\t\t\t  module.renderComAs(\"x_id\", <input />, false, false);\r\n\t\t  }}>replace</button>\r\n\t\t  <button onClick={() =>{\r\n\t\t\t  module.renderComAs(\"x_id\", false, <div>before</div>, false);\t\t  \r\n\t\t  }}>insert before</button>\r\n\t\t  <button onClick={() =>{\r\n\t\t\t  module.renderComAs(\"x_id\", false, false, <div>after</div>);\t\t  \r\n\t\t  }}>insert after</button>\t\t  \r\n\t\t  <button onClick={() =>{\r\n\t\t\t  module.renderComAs(\"x_id\", null, null, null);\r\n\t\t  }}>restore</button>\r\n\t  </div>);\r\n  };\r\n```\r\n### 2.4. useModule instance - material-UI plugin functions\r\n#### `showSnackbar`\r\n ----\r\n> **showSnackbar ( message )**  \r\n> &emsp;&emsp;*To show a material-UI snackbar. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui )*  \r\n> **[parameters]**  \r\n> * **message** [required] : *String/Object, The message (String), or the props (Object) of the [Snackbar]( https://material-ui.com/api/snackbar )* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  // to show a snack bar\r\n  module.showSnackbar(\"snack message\");\r\n```\r\n#### `alert`\r\n ----\r\n> **alert ( title, description, okCaption )**  \r\n> &emsp;&emsp;*To show an material-UI alert window. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui ). You must use 'await' to call it, and it must be in an async function.*  \r\n> **[parameters]**  \r\n> * **title** [required] : *String, The title text* \r\n> * **description** [required] : *String, The description text* \r\n> * **okCaption** [optional] : *String, The caption text for OK button. Default is \"OK\".* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  (async()=>{\r\n      // to show an alert dialog\r\n      await module.alert(\"title\", \"desc\", \"O K\");\r\n  })();\r\n```\r\n#### `confirm`\r\n ----\r\n> **confirm ( title, description, okCaption, cancelCaption )**  \r\n> &emsp;&emsp;*To show an material-UI confirm window. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui ). You must use 'await' to call it, and it must be in an async function.*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Boolean, the confirm result.*  \r\n> **[parameters]**  \r\n> * **title** [required] : *String, The title text* \r\n> * **description** [required] : *String, The description text* \r\n> * **okCaption** [optional] : *String, The caption text for OK button. Default is \"OK\".* \r\n> * **cancelCaption** [optional] : *String, The caption text for cancel button. Default is \"Cancel\".* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  (async()=>{\r\n      // to show an confirm dialog\r\n      const result = await module.cofirm(\"title\", \"desc\");\r\n  })();\r\n```\r\n#### `prompt`\r\n ----\r\n> **prompt ( title, description, defaultValue, okCaption, cancelCaption )**  \r\n> &emsp;&emsp;*To show an material-UI prompt window. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui ). You must use 'await' to call it, and it must be in an async function.*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*String, the input text.*  \r\n> **[parameters]**  \r\n> * **title** [required] : *String, The title text* \r\n> * **description** [required] : *String, The description text* \r\n> * **defaultValue** [optional] : *String, The default value text. Default is empty string.* \r\n> * **okCaption** [optional] : *String, The caption text for OK button. Default is \"OK\".* \r\n> * **cancelCaption** [optional] : *String, The caption text for cancel button). Default is \"Cancel\".* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  (async()=>{\r\n      // to show an confirm dialog\r\n      const result = await module.prompt(\"title\", \"desc\");\r\n  })();\r\n```\r\n#### `showBackdrop`\r\n ----\r\n> **showBackdrop ( id, clickAway, style, transitionDuration, children)**  \r\n> &emsp;&emsp;*To show a backdrop for a given id. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui ).*  \r\n> **[parameters]**  \r\n> * **id** [optional] : *String, The backdrop id, default is 'default'* \r\n> * **clickAway** [optional] : *Boolean, To determine whether 'click' to hide the backdrop or not, default is true.* \r\n> * **style** [optional] : *Object, To determine the backdrop's style, default is {}.*   \r\n> * **transitionDuration** [optional] : *Number, The transition duration in ms. Default is 300.* \r\n> * **children** [optional] : *Array/Boolean, The children elements in the backdrop. Default is true > there'll be an CircularProgress in the backdrop.* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  module.showBackdrop( );\r\n```\r\n#### `hideBackdrop`\r\n ----\r\n> **hideBackdrop ( id )**  \r\n> &emsp;&emsp;*To hide a backdrop for a given id. It's an advanced function in material-UI plugin ( react-hook-module/plugin_mui ).*  \r\n> **[parameters]**  \r\n> * **id** [optional] : *String, The backdrop id, default is 'default'.* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import material-UI plugin\r\n  import \"react-hook-module/plugin_mui\";\r\n  //...\r\n  module.hideBackdrop( );\r\n```\r\n### 2.5. useModule instance - request  plugin functions\r\n#### `request`\r\n ----\r\n> **request ( url, data, method, baseURL, AUTH_TOKEN, header, config )**  \r\n> &emsp;&emsp;*To request data from a remote service endpoint, by [axios](https://github.com/axios/axios). It's an advanced function in request  plugin ( react-hook-module/plugin_request ). You must use 'await' to call it, and it must be in an async function.*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, the request result.*  \r\n> **[parameters]**  \r\n> * **url** [required] : *String, The url option for an [axios reqeust](https://github.com/axios/axios#request-config)* \r\n> * **data** [optional] : *Object/String, The data (ArrayBuffer, ArrayBufferView, URLSearchParams, FormData, File, Blob, or queryString) option for an  [axios reqeust](https://github.com/axios/axios#request-config) Default is null.* \r\n> * **method** [optional] : *String, The method (get/post/put/delete/patch/head/options) option for an  [axios reqeust](https://github.com/axios/axios#request-config). Default is 'get'.*   \r\n> * **baseURL** [optional] : *String, The base URL option for an  [axios reqeust](https://github.com/axios/axios#request-config). Default is empty string.*  \r\n> * **AUTH_TOKEN** [optional] : *String, The AUTH_TOKEN option for an  [axios reqeust](https://github.com/axios/axios#request-config). Default is null.*  \r\n> * **header** [optional] : *Object, The header option for an  [axios reqeust](https://github.com/axios/axios#request-config). Default is {}.*  \r\n> * **config** [optional] : *Object, The config option for an  [axios reqeust](https://github.com/axios/axios#request-config).Default is {}.*  \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import request plugin for \r\n  import \"react-hook-module/plugin_request\";\r\n  //...\r\n  const App = props => {\r\n      const { module } = useModule(props, { }); \r\n      return (\r\n        <div>\r\n          <button onClick={async () => {\r\n            const result = await  module.request(useModule.resolveURL(\"./service/endpoint\"));\r\n            console.log( result );\r\n          }}>module.request</button>\r\n        </div>\r\n      );\r\n  };\r\n``` \r\n#### `request.fetch`\r\n ----\r\n> **request.fetch(  )**  \r\n> &emsp;&emsp;*To fetch data for the useModule's default request, only for the props with req_execute=false. You must use 'await' to call it, and it must be in an async function.*  \r\n>  **[return]**  \r\n> &emsp;&emsp;*Object, the request result.*  \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  import { If } from \"react-hook-module\";\r\n  // must import request plugin\r\n  import \"react-hook-module/plugin_request\";\r\n  //...\r\n  const App = props => {\r\n      // If no 'req_url', the request will be undefined \r\n      const { module, request } = useModule(props, {\r\n        props:{\r\n          req_url: useModule.resolveUrl(\"./service/endpoint\"),\r\n          req_execute: false\r\n        }\r\n      }); \r\n      return (\r\n        <div>\r\n          <div>Status: [{request.status}]</div>\r\n          <If condition={request.error} >\r\n            error: {request.error && JSON.stringify(request.error)}\r\n          </If>\r\n          <If condition={request.response} >\r\n            data: {request.response && JSON.stringify(request.response)}\r\n          </If>\r\n          <button onClick={async () => {\r\n            const result = await request.fetch();\r\n            console.log( result );\r\n          }}>fetch</button>\r\n        </div>\r\n      );\r\n  };\r\n```\r\nNormally, you don't need to set 'req_execute' to false for the default request in an useModule. The default request will be executed automatically.\r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  import { If } from \"react-hook-module\";\r\n  // must import request plugin\r\n  import \"react-hook-module/plugin_request\";\r\n  //...\r\n  const App = props => {\r\n      // If no 'req_url', the request will be undefined \r\n      const { module, request } = useModule(props, {\r\n        props:{\r\n          req_url: useModule.resolveUrl(\"./service/endpoint\")\r\n        }\r\n      }); \r\n      return (\r\n        <div>\r\n          <div>Status: [{request.status}]</div>\r\n          <If condition={request.error} >\r\n            error: {request.error && JSON.stringify(request.error)}\r\n          </If>\r\n          <If condition={request.response} >\r\n            data: {request.response && JSON.stringify(request.response)}\r\n          </If>\r\n        </div>\r\n      );\r\n  };\r\n```\r\n#### `request.cancel`\r\n ----\r\n> **request.cancel(  )**  \r\n> &emsp;&emsp;*To cancel the useModule's default request.*  \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import request plugin\r\n  import \"react-hook-module/plugin_request\";\r\n  //...\r\n  const App = props => {\r\n    // If no 'req_url', the request will be undefined \r\n    const { module, request } = useModule(props, {\r\n      props:{\r\n        req_url: useModule.resolveUrl(\"./service/endpoint\")\r\n      }\r\n    }); \r\n    // cancel the useModule's default request\r\n    React.useEffect(() => request.cancel(), [request]);\r\n      return (\r\n        <div>\r\n          <div>Status: [{request.status}]</div>\r\n        </div>\r\n      );\r\n  };\r\n```\r\n### 2.6. useModule instance - router plugin functions\r\n#### `router.navigate`\r\n ----\r\n> **router.navigate ( route, state )**  \r\n> &emsp;&emsp;*To navigate to target route (document). *  \r\n> **[parameters]**  \r\n> * **route** [required] : *String, The route path.* \r\n> * **state** [optional] : *Object, The state. [router.navigate('/', {replace: true})] equals to [router.replace('/')] .* \r\n#### `router.replace`\r\n ----\r\n> **router.replace( route )**  \r\n> &emsp;&emsp;*To replace the document by target route. *   \r\n> **[parameters]**  \r\n> * **route** [required] : *String, The route path.*   \r\n\r\n--->`router.replace(route)` equlas to `router.navigate(route ,{replace: true})`.\r\n\r\n#### `router.setSearchParams`\r\n ----\r\n> **router.setSearchParams( params )**  \r\n> &emsp;&emsp;*[for useModule router plugin] To update the search parameters. *  \r\n> **[parameters]**  \r\n> * **params** [required] : *Object/String, The search params. Object or queryString.* \r\n```javascript\r\n  import { useModule } from \"react-hook-module\";\r\n  // must import request plugin\r\n  import { BrowserRouter as  Router, RelativeRouter } from  \"react-hook-module/plugin_router\";\r\n  //...\r\n  const App = props => {\r\n      // If no 'router' in props, or 'props.router' is false, the router will be undefined \r\n      const { module, router } = useModule(props, {\r\n        props:{\r\n          enableRouter : true\r\n        }\r\n      }); \r\n      return (\r\n        <Router>\r\n\t        <RelativeRouter>\r\n\t\t\t\t<div path=\"/path1\">path1</div>\r\n\t\t\t\t<div path=\"/path2\">path2</div>\r\n\t\t\t\t<div path=\"/about\">about</div>\r\n\t\t\t\t<div path=\"*\">Not Support</div>\r\n\t        </RelativeRouter>\r\n\t        <div>\r\n\t\t\t\t<button onClick={() => {\r\n\t\t\t\t\trouter.navigate('/about');\r\n\t\t\t\t}}>Route to \"/about\"</button>\r\n\t\t\t\t<button onClick={() => {\r\n\t\t\t\t\trouter.setSearchParams('k1=v1&k2=v2');\r\n\t\t\t\t}}>setSearchParams</button>\t\t\t\t\r\n\t        </div>\r\n        </Router>\r\n      );\r\n  };\r\n```\r\n### 2.7. useModule instance - auth plugin functions\r\n#### `auth.signIn`\r\n ----\r\n> **auth.signIn (  )**  \r\n> &emsp;&emsp;*To trigger the sign in action.*    \r\n#### `auth.signOut `\r\n ----\r\n> **auth.signOut (  )**  \r\n> &emsp;&emsp;*To trigger the sign out action.*  \r\n#### `auth.signUp `\r\n ----\r\n> **auth.signUp(  )**  \r\n> &emsp;&emsp;*To trigger the sign up action.*     \r\n\r\n**File - auth_fake.js**\r\n```javascript\r\n  import {utils} from \"react-hook-module\";\r\n  // singIn function\r\n  const signIn = function(){\r\n    const auth = this;\r\n    const user = {email:\"fake@email.com\"};\r\n    setTimeout(() => {\r\n      auth.setUser(user);\r\n      utils.setCookie(\"user\", user);\r\n    }, 500);\r\n  };\r\n  // signOut function\r\n  const signOut = function(){\r\n    this.setUser(null);\r\n    utils.removeCookie(\"user\");\r\n  };\r\n  // signUp function\r\n  const signUp = function(){\r\n    console.log(\"signUp function\");\r\n  };  \r\n  const authInit = function(){\r\n    const auth = this;\r\n    const user = utils.getCookie(\"user\");\r\n    user && auth.setUser(user);\r\n    return function(){\r\n      // nothing\r\n    };\r\n  };\r\n  export default {signIn, signOut, authInit};\r\n```\r\n**File - index.js**\r\n```javascript\r\n  import React from \"react\";\r\n  import ReactDOM from \"react-dom\";\r\n  import { useModule } from \"react-hook-module\";\r\n  import { ProvideAuth } from \"react-hook-module/plugin_auth\";\r\n  import App from \"./App\";\r\n  import configure from \"./auth_fake.js\";\r\n  ReactDOM.render( (\r\n    <React.StrictMode>\r\n      <ProvideAuth {...configure} >\r\n        <App path=\"/*\" />\r\n      </ProvideAuth>\r\n    </React.StrictMode>\r\n  ), document.getElementById(\"root\"));\r\n```\r\n**File - App.js**\r\n```javascript\r\n  import React from \"react\";\r\n  import { useModule } from \"react-hook-module\";\r\n  import { If } from \"react-hook-module\";\r\n  const App = props => {\r\n      // If no 'auth' in props, or 'props.auth' is false, the auth will be undefined \r\n      const { module, auth } = useModule(props, { enableAuth: true });\r\n      return (\r\n      <React.Fragment>\r\n        <If condition={auth && auth.user} >\r\n          <div> Signed in successfully!</div>\r\n          <div> User Email: {auth && auth.user && auth.user.email} </div>\r\n          <div> <button onClick={() => auth.signOut()}>Sign Out</button> </div>\r\n        </If>\r\n        <If condition={!auth || !auth.user} >\r\n          <div><button onClick={() => auth.signIn()}>Sign In</button></div>\r\n        </If>\r\n      </React.Fragment>\r\n    );\r\n  };\r\n```\r\n## 3. Quickstart\r\n### 3.1. Basic Demo\r\n```javascript\r\nimport React from \"react\";\r\nimport { useModule } from \"react-hook-module\";\r\n\r\nexport default (props) => {\r\n  const { module } = useModule(props, {\r\n    actions: {\r\n      callback: (msg) => module.updateState({ msg })\r\n    }\r\n  });\r\n  return (\r\n    <div style={{ border: \"1px dashed\", padding: \"1em\" }}>\r\n      <h2>useModule demo {\">\"} modules interaction</h2>\r\n      <div>\r\n        <strong>\r\n          {\"<\"}Module1{\">\"}\r\n        </strong>\r\n      </div>{\" \"}\r\n      <p />\r\n      <button\r\n        onClick={(e) =>\r\n          module.updateStateFor(\"alias_in_parent\", {\r\n            value: \"Value updated by updateState\"\r\n          })\r\n        }\r\n      >\r\n        updateState for Module2\r\n      </button>\r\n      {\" | \"}\r\n      <button\r\n        onClick={(e) =>\r\n          module.sendMessageTo(\r\n            \"alias_in_parent\",\r\n            \"Value updated by sendMessage\"\r\n          )\r\n        }\r\n      >\r\n        sendMessage to Module2\r\n      </button>\r\n      {\" | \"}\r\n      <button\r\n        onClick={(e) =>\r\n          useModule.dispatchActionTo(\"global_uid\", \"updValue\", [\r\n            \"Value updated by dispatchAction\"\r\n          ])\r\n        }\r\n      >\r\n        dispatchAction to Module2\r\n      </button>\r\n      <p />\r\n      <div> Callback Message: \"{module.state.msg || \"No callback yet\"}\"</div>\r\n      <p />\r\n      <Module2 usemodule_alias=\"alias_in_parent\" usemodule_parent={module} />\r\n      <Module2 usemodule_uid=\"global_uid\" />\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const Module2 = (props) => {\r\n  const { module } = useModule(props, {\r\n    props: {\r\n      onMessage: (value) => {\r\n        module.updateState({ value });\r\n        module.parent.dispatchAction(\"callback\", [\"Message received\"]);\r\n      }\r\n    },\r\n    actions: {\r\n      updValue: (value) => {\r\n        module.updateState({ value });\r\n      }\r\n    }\r\n  });\r\n  return (\r\n    <div style={{ border: \"1px dashed\", padding: \"1em\" }}>\r\n      <div>\r\n        <strong>\r\n          {\"<\"}Module2{\">\"}\r\n        </strong>{\" \"}\r\n        ( {props.usemodule_alias ? \"alias='\" + props.usemodule_alias + \"'\" : \"\"}{\" \"}\r\n        {props.usemodule_uid ? \"uid='\" + props.usemodule_uid + \"'\" : \"\"} )\r\n      </div>{\" \"}\r\n      <p />\r\n      value = \"<strong>{module.state.value}</strong>\"\r\n    </div>\r\n  );\r\n};\r\n```\r\n#### Screenshot\r\n<img src=\"https://raw.githubusercontent.com/linb/react-hook-module/master/image/demo1.png\"  width=\"600\">\r\n\r\n#### Module Tree\r\n```\r\n[root]\r\n  │  \r\n  ├─<Module1>\r\n  │     │  \r\n  │     └<Module2 usemodule_alias=\"alias_in_parent\">\r\n  │      \r\n  └<Module2 usemodule_uid=\"global_uid\">\r\n ```\r\n[Open the demo in CodeSandbox](https://codesandbox.io/s/thirsty-swirles-4iomy \"react-hook-module basic demo\")\r\n\r\n\r\n### 3.2. Meterial UI Demo\r\n```javascript\r\nimport React from \"react\";\r\nimport { useModule } from \"react-hook-module\";\r\nimport \"react-hook-module/plugin_mui\";\r\nimport { Button } from \"@material-ui/core\";\r\nimport { makeStyles } from \"@material-ui/core\";\r\nimport { Dialog } from \"@material-ui/core\";\r\nimport { TextField } from \"@material-ui/core\";\r\nimport { DialogActions } from \"@material-ui/core\";\r\nimport { DialogContent } from \"@material-ui/core\";\r\nimport { DialogContentText } from \"@material-ui/core\";\r\nimport { DialogTitle } from \"@material-ui/core\";\r\n\r\nconst useStyles4basic = makeStyles((theme) => ({\r\n  item: { margin: theme.spacing(1) },\r\n  container: { padding: theme.spacing(1) }\r\n}));\r\n\r\nconst Module_Dialog = (props) => {\r\n  const styles_basic = useStyles4basic(props || {});\r\n  const { module } = useModule(props, {});\r\n  return (\r\n    <React.Fragment>\r\n      <div>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"primary\"\r\n          className={styles_basic.item}\r\n          onClick={async (e) => {\r\n            await module.alert(\"Alert 1\");\r\n          }}\r\n        >\r\n          Alert 1\r\n        </Button>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"secondary\"\r\n          className={styles_basic.item}\r\n          onClick={async (e) => {\r\n            const rst = await module.confirm(\"Confirm 1\");\r\n            alert(rst);\r\n          }}\r\n        >\r\n          Confirm 1\r\n        </Button>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"default\"\r\n          className={styles_basic.item}\r\n          onClick={async (e) => {\r\n            const rst = await module.prompt(\"Prompt 1\");\r\n            alert(rst);\r\n          }}\r\n        >\r\n          Prompt 1\r\n        </Button>\r\n      </div>\r\n      <div>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"primary\"\r\n          className={styles_basic.item}\r\n          key=\"cyenksua\"\r\n          onClick={(e) => {\r\n            useModule.updateStateFor(\"Alert_1\", { open: true });\r\n          }}\r\n        >\r\n          Alert 2\r\n        </Button>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"secondary\"\r\n          className={styles_basic.item}\r\n          onClick={(e) => {\r\n            useModule.dispatchActionTo(\"Confirm_1\", \"open\");\r\n          }}\r\n        >\r\n          Confirm 2\r\n        </Button>\r\n        <Button\r\n          variant=\"contained\"\r\n          color=\"default\"\r\n          className={styles_basic.item}\r\n          onClick={(e) => {\r\n            useModule.sendMessageTo(\"Prompt_1\", \"open\");\r\n          }}\r\n        >\r\n          Prompt 2\r\n        </Button>\r\n      </div>\r\n\r\n      <Alert\r\n        open={false}\r\n        usemodule_alias=\"Alert_1\"\r\n        usemodule_parent=\"{module}\"\r\n        title=\"Alert 2\"\r\n        description=\"Description\"\r\n        onOK={() => alert(\"OK\")}\r\n      ></Alert>\r\n      <Confirm\r\n        open={false}\r\n        usemodule_alias=\"Confirm_1\"\r\n        usemodule_parent=\"{module}\"\r\n        title=\"Confirm 2\"\r\n        description=\"Description\"\r\n        onOK={() => alert(\"OK\")}\r\n        onCancel={() => alert(\"onCancel\")}\r\n      ></Confirm>\r\n      <Prompt\r\n        open={false}\r\n        usemodule_alias=\"Prompt_1\"\r\n        usemodule_parent=\"{module}\"\r\n        title=\"Prompt 2\"\r\n        description=\"Description\"\r\n        onOK={(txt) => alert(\"Result: \" + txt)}\r\n        onCancel={() => {\r\n          alert(\"onCancel\");\r\n        }}\r\n      ></Prompt>\r\n    </React.Fragment>\r\n  );\r\n};\r\n\r\nexport default Module_Dialog;\r\n\r\nexport const Alert = (props) => {\r\n  const { module } = useModule(props, {\r\n    props: {\r\n      open: true,\r\n      title: \"Title\",\r\n      description: \"Description\",\r\n      onOK: () => {}\r\n    },\r\n    state: {\r\n      open: false\r\n    },\r\n    actions: {\r\n      open: function () {\r\n        this.updateState({ open: true });\r\n      },\r\n      close: function () {\r\n        this.updateState({ open: false });\r\n      }\r\n    }\r\n  });\r\n  const [defaultState, setDefaultState] = React.useState({\r\n    open: false\r\n  });\r\n\r\n  return (\r\n    <Dialog\r\n      open={\r\n        (module.props && module.props.open) ||\r\n        (module.state && module.state.open)\r\n      }\r\n      onClose={() => module.dispatchAction(\"close\")}\r\n      fullWidth\r\n      aria-labelledby=\"alert_9za5tayt_title\"\r\n      aria-describedby=\"alert_9za5tayt_description\"\r\n      key=\"7e8gz5b3\"\r\n    >\r\n      <DialogTitle id=\"alert_9za5tayt_title\">\r\n        {\" \"}\r\n        {module.props && module.props.title}{\" \"}\r\n      </DialogTitle>\r\n      <DialogContent>\r\n        <DialogContentText id=\"alert_9za5tayt_description\">\r\n          {module.props && module.props.description}\r\n        </DialogContentText>\r\n      </DialogContent>\r\n      <DialogActions>\r\n        <Button\r\n          onClick={() => {\r\n            module.props.onOK();\r\n            module.dispatchAction(\"close\");\r\n          }}\r\n          color=\"primary\"\r\n        >\r\n          {\" \"}\r\n          OK{\" \"}\r\n        </Button>\r\n      </DialogActions>\r\n    </Dialog>\r\n  );\r\n};\r\n\r\nexport const Confirm = (props) => {\r\n  const { module } = useModule(props, {\r\n    props: {\r\n      open: true,\r\n      title: \"Title\",\r\n      description: \"Description\",\r\n      onOK: () => {},\r\n      onCancel: () => {}\r\n    },\r\n    state: {\r\n      open: false\r\n    },\r\n    actions: {\r\n      open: function () {\r\n        this.updateState({ open: true });\r\n      },\r\n      close: function () {\r\n        this.updateState({ open: false });\r\n      }\r\n    }\r\n  });\r\n  const [defaultState, setDefaultState] = React.useState({\r\n    open: false\r\n  });\r\n\r\n  return (\r\n    <Dialog\r\n      open={\r\n        (module.props && module.props.open) ||\r\n        (module.state && module.state.open)\r\n      }\r\n      onClose={() => module.dispatchAction(\"close\")}\r\n      fullWidth\r\n      aria-labelledby=\"confirm_jlh80pil_title\"\r\n      aria-describedby=\"confirm_jlh80pil_description\"\r\n      key=\"2h6e3jqi\"\r\n    >\r\n      <DialogTitle id=\"confirm_jlh80pil_title\">{props.title}</DialogTitle>\r\n      <DialogContent>\r\n        <DialogContentText id=\"confirm_jlh80pil_description\">\r\n          {props.description}\r\n        </DialogContentText>\r\n      </DialogContent>\r\n      <DialogActions>\r\n        <Button\r\n          onClick={() => {\r\n            module.props.onCancel();\r\n            module.dispatchAction(\"close\");\r\n          }}\r\n          color=\"secondary\"\r\n        >\r\n          Cancel\r\n        </Button>\r\n        <Button\r\n          onClick={() => {\r\n            module.props.onOK();\r\n            module.dispatchAction(\"close\");\r\n          }}\r\n          color=\"primary\"\r\n        >\r\n          OK\r\n        </Button>\r\n      </DialogActions>\r\n    </Dialog>\r\n  );\r\n};\r\n\r\nexport const Prompt = (props) => {\r\n  const { module } = useModule(props, {\r\n    props: {\r\n      open: true,\r\n      title: \"Title\",\r\n      description: \"Description\",\r\n      onOK: () => {},\r\n      onCancel: () => alert(9),\r\n      onMessage: (msg) => {\r\n        if (msg === \"open\") {\r\n          module.updateState({\r\n            open: true\r\n          });\r\n        }\r\n      }\r\n    },\r\n    state: {\r\n      open: false\r\n    },\r\n    actions: {\r\n      open: function () {\r\n        this.updateState({\r\n          open: true\r\n        });\r\n      },\r\n      close: function () {\r\n        this.updateState({\r\n          open: false\r\n        });\r\n      }\r\n    }\r\n  });\r\n  const [defaultState, setDefaultState] = React.useState({\r\n    open: false\r\n  });\r\n\r\n  return (\r\n    <Dialog\r\n      open={\r\n        (module.props && module.props.open) ||\r\n        (module.state && module.state.open)\r\n      }\r\n      onClose={() => module.dispatchAction(\"close\")}\r\n      fullWidth\r\n      aria-labelledby=\"prompt_fn69vqpc_title\"\r\n      aria-describedby=\"prompt_fn69vqpc_description\"\r\n      key=\"blg87o2c\"\r\n    >\r\n      <DialogTitle id=\"prompt_fn69vqpc_title\">{props.title}</DialogTitle>\r\n      <DialogContent>\r\n        <DialogContentText id=\"prompt_fn69vqpc_description\">\r\n          {props.description}\r\n        </DialogContentText>\r\n        <TextField\r\n          autoFocus\r\n          margin=\"dense\"\r\n          defaultValue=\"\"\r\n          fullWidth\r\n          onChange={(e) =>\r\n            setDefaultState(\r\n              Object.assign({}, defaultState, { text: e.target.value })\r\n            )\r\n          }\r\n        ></TextField>\r\n      </DialogContent>\r\n      <DialogActions>\r\n        <Button color=\"secondary\" onClick={() => props.onCancel()}>\r\n          Cancel\r\n        </Button>\r\n        <Button\r\n          onClick={() => {\r\n            props.onOK(defaultState.text);\r\n            module.dispatchAction(\"close\");\r\n          }}\r\n          color=\"primary\"\r\n        >\r\n          OK\r\n        </Button>\r\n      </DialogActions>\r\n    </Dialog>\r\n  );\r\n};\r\n\r\n```\r\n#### Screenshot\r\n<img src=\"https://raw.githubusercontent.com/linb/react-hook-module/master/image/demo2.png\"  width=\"600\">\r\n\r\n#### Module Tree\r\n```\r\n[root]\r\n  │  \r\n  └─<Module_Dialog >\r\n         │  \r\n         ├<Alert usemodule_alias=\"Alert_1\">\r\n         │  \r\n         ├<Confirm usemodule_alias=\"Confirm_1\">\r\n         │  \r\n         └<Prompt usemodule_uid=\"Prompt_uid\">\r\n```\r\n\r\n[Open the demo in CodeSandbox](https://codesandbox.io/s/strange-thompson-g4op5 \"react-hook-module Materail-UI demo\")\r\n \r\n## npm\r\n[npm link](https://www.npmjs.com/package/react-hook-module \"react-hook-module NPM\")\r\n","readmeFilename":"readme.md"}