Mon gestionnaire d'état pour React, Preact, Inferno

J'adore réinventer les vélos et autres objets utiles. Cela ne fonctionne pas toujours bien, mais le processus est intéressant. J'attire votre attention sur la bibliothèque de gestion d'état pour React, Preact (poids seulement 4,8Kb). La bibliothèque est encore en cours de développement, mais vous pouvez déjà l'essayer.





Commençons par un exemple de l'organisateur TODO préféré de tout le monde. Code source sur github . Commençons par créer le composant principal main.js.





// main.js
import React, { createElement, Component, createContext } from 'react';
import ReactDOM from 'react-dom';
import {Connect, Provider} from './store'
import Input from './InputComp'
import TodoList from './TodoList'
import LoadingComp from './LoadingComp'

const Main = () => (
  <Provider>
    <h1>Todo:</h1>
    <LoadingComp>
      <TodoList/>
    </LoadingComp>
    <hr/>
    <Input/>
  </Provider>
)

ReactDOM.render(<Main />, document.getElementById("app"));
      
      



Un autre côté. Nous avons besoin du magasin pour initialiser la bibliothèque, et ici nous spécifions également tous les fichiers nécessaires avec des actions. Dans notre exemple, ce sont actions.js et actionsSetup.js





// store.js

import React, { createElement, Component, createContext } from 'react';
import createStoreFactory from 'redoor';

//     actions.js  actionsSetup.js
import * as actions from './actions'
import * as actionsSetup from './actionsSetup'

//       React
const createStore = createStoreFactory({
  Component, 
  createContext, 
  createElement
});

//         
//    
const { Provider, Connect } = createStore([
  actions,
  actionsSetup
]);

export { Provider, Connect };
      
      







// actions.js

//         
// redoor     
// initState       ,
//   ,     
export const initState = {
    todos:[],
    value:'',
}

//     
//  state -   
//  args -      
//     
export const a_enter = ({state,args}) => {
  let {value,todos} = state;
  todos.push({
    id:(Math.random()+"").substr(2),
    value:value,
    done:false
  });
  return {
    value:'',
    todos
  }
}

//    
export const a_done = ({state,args}) => {
  let {todos} = state;
  let id = args.id;
  todos = todos.map(it=>(it.id === id ? (it.done = !it.done, it) : it))
  return {
    todos
  }
}

//    
export const a_delete = ({state,args}) => {
  let {todos} = state;
  let id = args.id;
  todos = todos.filter(it=>it.id !== id)
  return {
    todos
  }
}
      
      







// InputComp.js
import React from 'react';
import {Connect} from './store'

// redoor     cxRun   
//  
const Input = ({cxRun, value})=><label className="input">
  Todo:
  
  //        
  <input onChange={e=>cxRun({value:e.target.value})} 
					value={value} 
					type="text" 
  />
  
  //     a_enter   actions.js
  <button onClick={e=>cxRun('a_enter')} disabled={!value.length}>
		ok
	</button>
</label>

//   redoor     
export default Connect(Input);
      
      



cxRun . , actions.js.





.





// TodoList.js
import React from 'react';
import {Connect} from './store'

const Item = ({cxRun, it, v})=><div className="item">
  //   a_done,      
  //         args
  <div className="item_txt" onClick={e=>cxRun('a_done',it)}>
    {v+1}) {it.done ? <s>{it.value}</s> : <b>{it.value}</b>}
  </div>
  <div className="item_del" onClick={e=>cxRun('a_delete',it)}>
    &times;
  </div>
</div>

const TodoList = ({cxRun, todos})=><div className="todos">
  {
    todos.map((it,v)=><Item key={v} cxRun={cxRun} it={it} v={v}/>)
  }
</div>

export default Connect(TodoList);
      
      



. value todos. initState actions.js. initState , . , .





-- "_" "action". cxRun. state args.





state --





args -- cxRun. cxRun('a_delete', it), , args.





, .





? setState actions.js bindStateMethods.





//actions.js
let __setState;
let __getState;

//     
export const bindStateMethods = (getState, setState) => {
  __getState = getState;
  __setState = setState;
};

export const a_setup = async ({state,args}) => {
  __setState({loading:true});
  let data = await loading();
  __setState({
    loading:false,
    todos:data
  })
}
      
      



"a_load", , . , __getState .





Debugger

redoor-devtool. redoor localhost:8333. , . .





redoor-devtool:





yarn add redoor-devtool
      
      







npx redoor-devtool -o
      
      



la touche "-o" ouvrira chrome à http: // localhost: 8333 , où se trouvera le débogueur.





Conclusion

En mon nom personnel, je peux partager que j'ai déjà réalisé plusieurs projets en utilisant cette bibliothèque. C'était assez pratique de travailler avec lui dans un projet avec des sockets. Il y a, bien sûr, des fonctionnalités d'utilisation. Par exemple, rappelez-vous que toutes les actions sont «visibles» depuis tous les modules. Ce ne sera pas un problème si vous disposez d'une structure claire pour nommer vos actions. Dans mes projets, j'utilise cette dénomination "a_moduleName_actionName".





C'est tout pour le moment. S'il y a de l'intérêt - j'essaierai d'écrire une critique plus détaillée.








All Articles