Meu gerente estadual para React, Preact, Inferno

Adoro reinventar bicicletas e outros itens úteis. Nem sempre funciona bem, mas o processo é interessante. Chamo a sua atenção para a biblioteca de gerenciamento de estado para React, Preact (peso de apenas 4,8 Kb). A biblioteca ainda está em desenvolvimento, mas você já pode experimentá-la.





Vamos começar com um exemplo do organizador TODO favorito de todos. Código-fonte no github . Primeiro, vamos criar o componente 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"));
      
      



Outro lado. Precisamos do armazenamento para inicializar a biblioteca, e aqui também especificamos todos os arquivos necessários com ações. Em nosso exemplo, são actions.js e 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
      
      



a chave "-o" abrirá o Chrome em http: // localhost: 8333 , onde estará o depurador.





Conclusão

Em meu próprio nome, posso compartilhar que já fiz vários projetos usando esta biblioteca. Foi bastante conveniente trabalhar com ele em um projeto com soquetes. Existem, é claro, recursos de uso. Por exemplo, lembre-se de que todas as ações são "visíveis" em todos os módulos. Isso não será um problema se você tiver uma estrutura clara para nomear suas ações. Em meus projetos, eu uso esse nome "a_moduleName_actionName".





É tudo por agora. Se houver interesse - tentarei escrever uma revisão mais detalhada.








All Articles