Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

react-redux-controller

react-redux-controller is a library that adds some opinion to the react-redux binding of React components to the Redux store. It creates the entity of a Controller, which is intended to be the single point of integration between React and Redux. The controller passes data and callbacks to the UI components via the React context. It's one solution to the question of how to get data and controller-like methods (e.g. event handlers) to the React UI components.

Philosophy

This library takes the opinion that React components should solely be focused on the job of rendering and capturing user input, and that Redux actions and reducers should be soley focused on the job of managing the store and providing a view of the state of the store in the form of selectors. The plumbing of distributing data to components, as well as deciding what to fetch, when to fetch, how to manage latency, and what to do with error handling, should be vested in an explicit controller layer.

This differs from alternative methods in a number of ways:

  • The ancestors of a component are not responsible for conveying dependencies to via props -- particularly when it comes to dependencies the ancestors don't use themselves.
  • The components are not coupled to Redux in any way -- no connect distributed throughout the component tree.
  • There are no smart components. Well there's one, but it's hidden inside the Controller.
  • Action creators do not perform any fetching. They are only responsible for constructing action objects, as is the case in vanilla Redux, with no middleware needed.

Usage

The controller factory requires 3 parameters:

  • The root component of the UI component tree.
  • An object that holds controller generator functions.
  • Any number of selector bundles, which are likely simply imported selector modules, each selector annotated a propType that indicates what kind of data it provides.

The functionality of the controller layer is implemented using generator functions. Within these functions, yield may be used await the results of Promises and to request selector values and root component properties. As a very rough sketch of how you might use this library:

// controllers/app_controller.jsimport{controller,getProps}from'react-redux-controller';importAppLayoutfrom'../components/app_layout';import*asactionsfrom'../actions';import*asmySelectorsfrom'../selectors/my_selectors';constcontrollerGenerators={*initialize(){// ... any code that should run before initial render (like loading actions)},*onUserActivity(meaningfulParam){const{ dispatch, otherData }=yieldgetProps;dispatch(actions.fetchingData());try{constapiData=yieldhttpRequest(`http://myapi.com/${otherData}`);returndispatch(actions.fetchingSuccessful(apiData));}catch(err){returndispatch(actions.errorFetching(err));}},// ... other controller generators follow};constselectorBundles=[mySelectors,];exportdefaultcontroller(AppLayout,controllerGenerators,selectorBundles);

Example

To see an in-depth example of usage of this library, the async example from the redux guide is ported to use the controller approach in this repo.

About

Library for creating a controller layer to link React and Redux, on top of react-redux.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages