Xstoreと呼ばれるReactアプリケーション用の使いやすい状態コンテナー

親愛なる同僚の皆さん、React xstoreアプリケーションの状態を管理するためのコンテナーに注意を向けて非難します。 大きくてキラキラ輝くReduxバイクの隣にあるのは、間違いなくこのような小さな子供用バイクです。 私たちJavaScriptプログラマーは皆、とても大きくてペースの遅い自転車製造工場です。







多かれ少なかれ初心者でも初心者でも、React JavaScript Reduxプログラマーとの知り合いは少し複雑に見えるかもしれません。







よく見てみましょう。







設置



npm install --save xstore
      
      





使用する



最初に、リポジトリに「ハンドラ」を追加する必要があります。

(ハンドラーの例を下のブロックに示します)







index.js







 import React from 'react' import ReactDOM from 'react-dom' import Store from 'xstore' import App from './components/App' import user from './store_handlers/user' import dictionary from './store_handlers/dictionary' //       "_". //       : user  dictionary. Store.addHandlers({ user, dictionary }); ReactDOM.render( <App/>, document.getElementById('root') );
      
      





以下は、「ユーザー」ハンドラーの例です。

ユーザーリポジトリの初期状態を判断するために必要なリデューサーの初期化が含まれています。







./store_handlers/user.js







 import axios from 'axios' const DEFAULT_STATE = { name: 'user', status: 'alive' } /** =============== Reducers =============== */ //       . //     ,     . //   ,     . //    this.props.dispatch('USER_INIT'). const init = () => { return DEFAULT_STATE; } // this.props.dispatch('USER_CHANGED', {name: 'NewName'}) const changed = (state, data) => { return { ...state, ...data } } /** =============== Actions =============== */ // this.props.doAction('USER_CHANGE', {data}) const change = ({dispatch}, data) => { // {dispatch, doAction, getState, state} dispatch('USER_CHANGED', data); } // this.props.doAction('USER_LOAD', {id: userId}) const load = ({dispatch}, data) => { // {dispatch, doAction, getState, state} axios.get('/api/load.php', data) .then(({data}) => { dispatch('USER_CHANGED', data); }); } //          export default { actions: { load, change // remove, save, add_item, remove_this_extra_item, ..... }, reducers: { init, changed // removed, saved, item_added, this_extra_item_removed, ..... } }
      
      





以下は、コンポーネントをリポジトリに接続する方法の例です。







./components/ComponentToConnect/index.js







 import React from 'react' import Store from 'xstore' class ComponentToConnect extends React.Component { render() { //  user  dictionary    . let {user, dictionary} = this.props; return ( <div className="some-component"> .... </div> ) } loadUser(userId) { //    . this.props.doAction('USER_LOAD', {id: userId}); } setUser(userData) { //    . //         . this.props.dispatch('USER_CHANGED', userData); } } //    . const params = { has: 'user, dictionary' } export default Store.connect(ComponentToConnect, params);
      
      





接続に使用可能なparamsオプション:







 { //  ,     : has: 'user, dictionary', //  -: has: ['user', 'dictionary'], //       : has: 'user:name|status, dictionary:userStatuses', //  has: ['user:name|status', 'dictionary:userStatuses'], //      ,    . shouldHave: 'user,dictionary', //  shouldHave: ['user', 'dictionary'], //         ,   true. //      "name", "status", "userStatuses"  "user"  "dictionary" flat: true, // ,      ,    flat = true. //      "user_name", "user_status", "dictionary_userStatuses" withPrefix: true, //      . //       ,  "has"   . handlers: { user, dictionary } }
      
      





パブリックリポジトリメソッドのリスト:







 import Store from 'xstore' //         : let state = Store.getState(); //         "user": let userState = Store.getState('user'); //   "name"   "user": let userName = Store.getState('user.name'); //     0   "items"   "user": let someItem = Store.getState('user.items.0'); //  : Store.addHandlers({ user: userHandler, dictionary: dictionaryHandler }) //   "load"  "user": //       ,      . Store.doAction('USER_LOAD', {id: userId}); //   "loaded"  "user": Store.dispatch('USER_LOADED', data); //     : Store.connect(Component, params);
      
      





そして、それがどのように機能するかについて:



「connect」メソッドは、新しいHOCクラスXStoreConnectを作成します。これは、コンポーネントとストレージの相互作用のすべてのロジックを隠します。 このクラスはストレージの変更にサブスクライブし、そこで何らかの変更が発生すると、外部呼び出しから保護されたsetStateメソッドを呼び出し(たとえば、this.refs.xStoreConnect.setState(...)を介して)、その後、このコンポーネントが再描画され、それによって更新されますラップされたコンポーネントの小道具。

ラッパーコンポーネントの状態を直接変更するthis.refs.xStoreConnect.state =何も何も起こらない場合、このクラスは埋め込みデータを見つけて削除できます。







ラッパーコンポーネントコード
 // ....      const LOCAL_OBJECT_CHECKER = {}; const connect = (ComponentToConnect, connectProps) => { let ready = false; let { has, handlers, shouldHave: shouldHaveString, flat, withPrefix } = connectProps; if (!has && handlers instanceof Object) { has = Object.keys(handlers); } let shouldHave = []; if (typeof shouldHaveString == 'string') { shouldHaveString = shouldHaveString.split(','); for (let item of shouldHaveString) { if (item) { shouldHave.push(item.trim()); } } } let doUnsubscribe, doCleanState, stateItemsQuantity; return class XStoreConnect extends React.Component { constructor() { super(); const updater = (state) => { stateItemsQuantity = Object.keys(state).length; if (ready) { this.setState(state, LOCAL_OBJECT_CHECKER); } else { this.state = state; } } doUnsubscribe = () => { unsubscribe(updater); } doCleanState = () => { cleanStateFromInjectedItems(updater, this.state); } subscribe(updater, {has, handlers, flat, withPrefix}); } setState(state, localObjectChecker) { if (state instanceof Object && localObjectChecker === LOCAL_OBJECT_CHECKER) { super.setState(state); } } componentWillMount() { ready = true; } componentWillUnmount() { ready = false; doUnsubscribe(); } render() { let {props, state} = this; let newStateKeysQuantity = Object.keys(state).length; if (stateItemsQuantity != newStateKeysQuantity) { doCleanState(); } for (let item of shouldHave) { if (state[item] === undefined) { return null; } } let componentProps = { ...props, ...state, doAction, dispatch }; return <ComponentToConnect {...componentProps}/> } } }
      
      





コマンドラインからハンドラーファイルを生成する:



 npm install -g xstore xstore create-handler filename
      
      





「package.json」の「scripts」で記述することもできます。







 { scripts: { "create-handler": "node node_modules/xstore/bin/exec.js" } } npm run create-handler filename
      
      





このコマンドは、ハンドラーのテンプレートコードを使用してfilename.jsファイル(存在しない場合)を作成します。







それだけです、簡単ですよね? これでキックできます。 親愛なる同僚のアドバイスと合理的な批判を喜んでいます。








All Articles