{"id":15673539,"url":"https://github.com/jwebcoder/recost","last_synced_at":"2025-05-06T22:42:49.895Z","repository":{"id":32428947,"uuid":"133194023","full_name":"JWebCoder/recost","owner":"JWebCoder","description":"React context state management system","archived":false,"fork":false,"pushed_at":"2023-07-18T20:56:51.000Z","size":643,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T03:41:20.513Z","etag":null,"topics":["context","js","react","state"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JWebCoder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"JWebCoder","patreon":"jwebcoder","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-05-13T00:39:26.000Z","updated_at":"2023-10-18T21:52:53.000Z","dependencies_parsed_at":"2024-10-23T11:25:22.792Z","dependency_job_id":null,"html_url":"https://github.com/JWebCoder/recost","commit_stats":{"total_commits":58,"total_committers":6,"mean_commits":9.666666666666666,"dds":0.6551724137931034,"last_synced_commit":"a4ff4a5d34461f709115ac0db51fd51febefa2a5"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWebCoder%2Frecost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWebCoder%2Frecost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWebCoder%2Frecost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWebCoder%2Frecost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JWebCoder","download_url":"https://codeload.github.com/JWebCoder/recost/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252782441,"owners_count":21803378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["context","js","react","state"],"created_at":"2024-10-03T15:41:10.554Z","updated_at":"2025-05-06T22:42:49.867Z","avatar_url":"https://github.com/JWebCoder.png","language":"TypeScript","funding_links":["https://github.com/sponsors/JWebCoder","https://patreon.com/jwebcoder"],"categories":[],"sub_categories":[],"readme":"# Recost\n\nReact context state management system\n\n## Getting Started\n\nThese instructions will get you a copy of the project up and running on your local machine for development and testing purposes.\n\n### Installing\n\nUse **yarn** or **npm** to install the package in your React Application\n\n    yarn add recost\n\n### Usage\n\nNext you need to **initialize the context** with a **reducer** for your application.\n\n#### index.js\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport App from './App'\nimport initContext, { Provider } from 'recost'\n\n// create a reducer function\nconst reducer = (state, action) =\u003e {\n  if (action.type === 'COUNT') {\n    return {\n      ...state,\n      count: state.count + 1\n    }\n  }\n\n  return state\n}\n\n// define the initial state for the application\nconst initialState = {\n  count: 1\n}\n\n// initialize the context\ninitContext(initialState, reducer)\n\nReactDOM.render(\n  \u003cProvider\u003e // add the Provider component to your application\n    \u003cApp/\u003e\n  \u003c/Provider\u003e,\n  document.getElementById('root')\n)\n```\n\nNow you can use the dispatcher and the state anywhere in the code\n\n#### App.js\n\n```js\nimport React, { Component } from 'react'\nimport { dispatch, withState } from 'recost'\n\nlet Count = (props) =\u003e {\n  return \u003cp\u003e{props.count}\u003c/p\u003e\n}\n\nconst mapStateToProps = (state) =\u003e ({\n  count: state.count\n})\n\nCount = withState(mapStateToProps)(Count)\n\nclass App extends Component {\n  onClickButton() {\n    dispatch({\n      type: 'COUNT'\n    })\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cCount/\u003e\n        \u003cbutton onClick={this.onClickButton}\u003e\n          Increase\n        \u003c/button\u003e\n      \u003c/div\u003e\n    )\n  }\n}\n\nexport default App\n```\n\n## Using middleware\n\n### Available middleware\n\n[recost-persist](https://github.com/JWebCoder/recost-persist) - persist/hydrate state using localstorage\n[recost-logger](https://github.com/JWebCoder/recost-logger) - logs state changes when in development mode\n\n### Create your own\n\nIn this example we have added two middleware functions.\n\nA **logger**, that will run **before** and **after** the state changes logging the changes.\n\n#### logger.js\n\n```js\nconst before = (state, action) =\u003e {\n  console.log('State before action:', state)\n  console.log('Full action:', action)\n}\n\nconst after = (state, action) =\u003e {\n  console.log('State after action:', state)\n}\n\nexport {\n  before,\n  after\n}\n```\n\nAnd a **callAPI**, that runs **before** each state change.\n\n#### callAPI.js\n\n```js\nconst before = (state, action, dispatch) =\u003e {\n  if (action.type === 'COUNT_API') {\n    setTimeout( // simulates and api call\n      () =\u003e {\n        dispatch({\n          type: 'SUCCESS_COUNT'\n        })\n      }\n      , 1000\n    )\n  }\n}\n\nexport {\n  before\n}\n```\n\nNow we just need to add the new middleware to the context\n\n#### index.js\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport App from './App'\nimport initContext, { Provider } from 'recost'\nimport * as logger from './Context/logger'\nimport * as callAPI from './Context/callAPI'\n\n// create a reducer function\nconst reducer = (state, action) =\u003e {\n  if (action.type === 'COUNT') {\n    return {\n      ...state,\n      count: state.count + 1\n    }\n  }\n\n  return state\n}\n\n// define the initial state for the application\nconst initialState = {\n  count: 1\n}\n\n// initialize the context with the middleware\ninitContext(initialState, reducer, [\n  logger,\n  callAPI\n])\n\nReactDOM.render(\n  \u003cProvider\u003e // add the Provider component to your application\n    \u003cApp/\u003e\n  \u003c/Provider\u003e,\n  document.getElementById('root')\n)\n```\n\n## API definition\n\n### initContext\n\nCreates a new application context\n\n```js\nimport initContext from 'recost'\n\ninitContext(initialState, reducer, middleware)\n```\n\n| Params       | required | description                                                               |\n| ------------ | -------- | ------------------------------------------------------------------------- |\n| initialState | yes      | initial application state                                                 |\n| reducer      | yes      | function that generates new state based on actions                        |\n| middleware   | yes      | Array of middleware that can run before or after the reducer taking place |\n\n#### initialState\n\nDefaults to an empty object `{}`\n\n#### reducer\n\n```js\nconst reducer = (state, action) =\u003e {\n  if (action.type === 'COUNT') {\n    return {\n      ...state,\n      count: state.count + 1\n    }\n  }\n\n  return state\n}\n```\n\n| Params | description                                     |\n| ------ | ----------------------------------------------- |\n| state  | current application state                       |\n| action | action object passed by the dispatcher function |\n\n#### middleware\n\nDefaults to an empty array `[]`\n\n### dispatch\n\nDispatches an action that will trigger a state change\n\n```js\nimport { dispatch } from 'recost'\n\ndispatch(actionObject)\n```\n\n| Params       | required | description                                                       |\n| ------------ | -------- | ----------------------------------------------------------------- |\n| actionObject | yes      | object containing the type of action and the payload if necessary |\n\n#### actionObject\n\n```js\ndispatch({\n  type: 'COUNT',\n  payload: null // this property is only required if we want to pass in some data\n})\n```\n\n### withState\n\nComposed function that takes a mapStateToProps function and a component\n\n```js\nimport { withState } from 'recost'\n\nWrappedComponent = withState(mapStateToProps)(Component)\n```\n\n| Params          | required | description                                                                                                                 |\n| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- |\n| mapStateToProps | no       | function that receives the full state and return a portion of it, if not defined, the entire state is sent to the component |\n| component       | yes      | component to wrap with state                                                                                                |\n\n#### mapStateToProps\n\n```js\nconst mapStateToProps = (state) =\u003e ({\n  count: state.count\n})\n```\n\n#### component\n\n```js\nconst Count = (props) =\u003e {\n  return \u003cp\u003e{props.count}\u003c/p\u003e\n}\n\nconst WrappedCount = withState(mapStateToProps)(Count)\n```\n\nor\n\n```js\nclass Count extends React.[PureComponent|Component] {\n  render() {\n    return \u003cp\u003e{this.props.count}\u003c/p\u003e\n  }\n}\n\nconst WrappedCount = withState(mapStateToProps)(Count)\n```\n\n### Provider\n\nProvider component, sets where we want to deliver our context\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport { Provider } from 'recost'\n\nReactDOM.render(\n  \u003cProvider\u003e\n    \u003cApp/\u003e\n  \u003c/Provider\u003e,\n  document.getElementById('root')\n)\n```\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).\n\n## Authors\n\n-   **João Moura** - _Initial work_ - [JWebCoder](https://github.com/JWebCoder)\n\n\u003c!--\nSee also the list of [contributors](CONTRIBUTORS.md) who participated in this project.\n--\u003e\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n\n## Acknowledgments\n\n-   Inspired by [Statty](https://github.com/vesparny/statty) and [Redux](https://redux.js.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwebcoder%2Frecost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwebcoder%2Frecost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwebcoder%2Frecost/lists"}