edu

Five Interesting Ways to Use Array.reduce() (And One Boring Way)

Chris Ferdinandi turns the heat down low and lets the sauce reduce while we take a look at how to add spice to our source with a sprinkling of Array.reduce(). Just a little ingenuity with the humblest of functions.


Of all the modern array methods, the one I had the hardest time wrapping my head around was Array.reduce().

On the surface, it seems like a simple, boring method that doesn’t do much. But below its humble exterior, Array.reduce() is actually a powerful, flexible addition to your developer toolkit.

Today, we’re going to look at some cool things you can do with Array.reduce().

How Array.reduce() works

Most of the modern array methods return a new array. The Array.reduce() method is a bit more flexible. It can return anything. Its purpose is to take an array and condense its content into a single value.

That value can be a number, a string, or even an object or new array. That’s the part that’s always tripped me up – I didn’t realize just how flexible it is!

The syntax

The Array.reduce() accepts two arguments: a callback method to run against each item in the array, and a starting value.

The callback also accepts two arguments: the accumulator, which is the current combined value, and the current item in the loop. Whatever you return is used as the accumulator for the next item in the loop. On the very first loop, that starting value is used instead.

var myNewArray = [].reduce(function (accumulator, current) {
  return accumulator;
}, starting);

Let’s look at some examples to make this all tangible.

1. Adding numbers together

Let’s say you had an array of numbers that you wanted to add together. Using Array.forEach(), you might do something like this:

var total = 0;

[1, 2, 3].forEach(function (num) {
  total += num;
});

This is the cliche example for using Array.reduce(). I find the word accumulator confusing, so in this example, I’m calling it sum, because that’s what it is.

var total = [1, 2, 3].reduce(function (sum, current) {
  return sum + current;
}, 0);

Here, we pass in 0 as our starting value.

In the callback, we add the current value to the sum, which has our starting value of 0 on the first loop, then 1 (the starting value of 0 plus the item value of 1), then 3 (the sum value of 1 plus the item value of 2), and so on.

Here’s a demo.

2. Combining multiple array methods into Array.map() and Array.filter() into a single step

Imagine you had an array of wizards at Hogwarts.

var wizards = [
  {
    name: 'Harry Potter',
    house: 'Gryfindor'
  },
  {
    name: 'Cedric Diggory',
    house: 'Hufflepuff'
  },
  {
    name: 'Tonks',
    house: 'Hufflepuff'
  },
  {
    name: 'Ronald Weasley',
    house: 'Gryfindor'
  },
  {
    name: 'Hermione Granger',
    house: 'Gryfindor'
  }
];

You want to create a new array that contains just the names of wizards who are in Hufflepuff. One way you could do that is by using the Array.filter() method to get back just wizards whose house property is Hufflepuff. Then, you’d use the Array.map() method to create a new array containing just the name property for the remaining wizards.

// Get the names of the wizards in Hufflepuff
var hufflepuff = wizards.filter(function (wizard) {
  return wizard.house === 'Hufflepuff';
}).map(function (wizard) {
  return wizard.name;
});

With the Array.reduce() method, we can get the same array in a single pass, improving our performance. You pass in an empty array ([]) as the starting value. On each pass, you check to see if the wizard.house is Hufflepuff. If it is, you push it to the newArr (our accumulator in this example). If not, you do nothing.

Either way, you return the newArr to become the accumulator on the next pass.

// Get the names of the wizards in Hufflepuff
var hufflepuff = wizards.reduce(function (newArr, wizard) {
  if (wizard.house === 'Hufflepuff') {
    newArr.push(wizard.name);
  }
  return newArr;
}, []);

Here’s another demo.

3. Creating markup from an array

What if, instead of creating an array of names, we wanted to create an unordered list of wizards in Hufflepuff? Instead of passing an empty array into Array.reduce() as our starting value, we’ll pass in an empty string ('') and call it html.

If the wizard.house equals Hufflepuff, we’ll concatenate our html string with the wizard.name wrapped in an opening and closing list item (li). Then, we’ll return the html to become the accumulator on the next loop.

// Create a list of wizards in Hufflepuff
var hufflepuffList = wizards.reduce(function (html, wizard) {
  if (wizard.house === 'Hufflepuff') {
    html += '<li>' + wizard.name + '</li>';
  }
  return html;
}, '');

Add an opening and closing unordered list element before and after Array.reduce(), and you’re ready to inject your markup string into the DOM.

// Create a list of wizards in Hufflepuff
var hufflepuffList = '<ul>' + wizards.reduce(function (html, wizard) {
  if (wizard.house === 'Hufflepuff') {
    html += '<li>' + wizard.name + '</li>';
  }
  return html;
}, '') + '</ul>';

See it in action here.

4. Grouping similar items in an array together

The lodash library has a groupBy() method takes a collection of items as an array and groups them together into an object based on some criteria.

Let’s say you want an array of numbers.

If you wanted to group all of the items in numbers together based on their integer value, you would do this with lodash.

var numbers = [6.1, 4.2, 6.3];

// returns {'4': [4.2], '6': [6.1, 6.3]}
_.groupBy(numbers, Math.floor);

If you had an array of words, and you wanted to group the items in words by their length, you would do this.

var words = ['one', 'two', 'three'];

// returns {'3': ['one', 'two'], '5': ['three']}
_.groupBy(words, 'length');

Creating a groupBy() function with Array.reduce()

You can recreate that same functionality using the Array.reduce() method.

We’ll create a helper function, groupBy(), that accepts the array and criteria to sort by as arguments. Inside groupBy(), we’ll run Array.reduce() on our array, passing in an empty object ({}) as our starting point, and return the result.

var groupBy = function (arr, criteria) {
  return arr.reduce(function (obj, item) {
    // Some code will go here...
  }, {});
};

Inside the Array.reduce() callback function, we’ll check to see if the criteria is a function, or a property of the item. Then we’ll get its value from the current item.

If there’s no property in the obj with that value yet, we’ll create it and assign an empty array as its value. Finally, we’ll push the item to that key, and return the object as the accumulator for the next loop.

var groupBy = function (arr, criteria) {
  return arr.reduce(function (obj, item) {

    // Check if the criteria is a function to run on the item or a property of it
    var key = typeof criteria === 'function' ? criteria(item) : item[criteria];

    // If the key doesn't exist yet, create it
    if (!obj.hasOwnProperty(key)) {
      obj[key] = [];
    }

    // Push the value to the object
    obj[key].push(item);

    // Return the object to the next item in the loop
    return obj;

  }, {});
};

Here’s a demo of the completed helper function.

Special thanks to Tom Bremer for helping me make some improvements to this one. You can find this helper function and more like it on the Vanilla JS Toolkit.

5. Combining data from two sources into an array

Remember our array of wizards?

var wizards = [
  {
    name: 'Harry Potter',
    house: 'Gryfindor'
  },
  {
    name: 'Cedric Diggory',
    house: 'Hufflepuff'
  },
  {
    name: 'Tonks',
    house: 'Hufflepuff'
  },
  {
    name: 'Ronald Weasley',
    house: 'Gryfindor'
  },
  {
    name: 'Hermione Granger',
    house: 'Gryfindor'
  }
];

What if you had another data set, an object of house points each wizard has earned.

var points = {
  HarryPotter: 500,
  CedricDiggory: 750,
  RonaldWeasley: 100,
  HermioneGranger: 1270
};

Imagine you wanted to combine both sets of data into a single array, with the number of points added to each wizard’s data in the wizards array. How would you do it?

The Array.reduce() method is perfect for this!

var wizardsWithPoints = wizards.reduce(function (arr, wizard) {

  // Get the key for the points object by removing spaces from the wizard's name
  var key = wizard.name.replace(' ', '');

  // If the wizard has points, add them
  // Otherwise, set them to 0
  if (points[key]) {
    wizard.points = points[key];
  } else {
    wizard.points = 0;
  }

  // Push the wizard object to the new array
  arr.push(wizard);

  // Return the array
  return arr;

}, []);

Here’s a demo combining data from two sources into an array.

6. Combining data from two sources into an object

What if you instead wanted to combine the two data sources into an object, where each wizard’s name was the key, and their house and points were properties? Again, the Array.reduce() method is perfect for this.

var wizardsAsAnObject = wizards.reduce(function (obj, wizard) {

  // Get the key for the points object by removing spaces from the wizard's name
  var key = wizard.name.replace(' ', '');

  // If the wizard has points, add them
  // Otherwise, set them to 0
  if (points[key]) {
    wizard.points = points[key];
  } else {
    wizard.points = 0;
  }

  // Remove the name property
  delete wizard.name;

  // Add wizard data to the new object
  obj[key] = wizard;

  // Return the array
  return obj;

}, {});

Here’s a demo combining two data sets into an object.

Should you use Array.reduce() more?

The Array.reduce() method has gone from being something I thought was pointless to my favorite JavaScript method. So, should you use it? And when?

The Array.reduce() method has fantastic browser support. It works in all modern browsers, and IE9 and above. It’s been supported in mobile browsers for a long time, too. If you need to go back even further than that, you can add a polyfill to push support back to IE6.

The biggest complaint you can make about Array.reduce() is that it’s confusing for people who have never encountered it before. Combining Array.filter() with Array.map() is slower to run and involves extra steps, but it’s easier to read. It’s obvious from the names of the methods what they’re supposed to be doing.

That said, there are times where Array.reduce() makes things that would be complicated more simple rather than more complicated. The groupBy() helper function is a good example.

Ultimately, this is another tool to add to your toolkit. A tool that, if used right, can give you super powers.


About the author

Chris Ferdinandi helps people learn vanilla JavaScript. He believes there’s a simpler, more resilient way to make things for the web.

Chris is the author of the Vanilla JS Pocket Guide series, creator of the Vanilla JS Academy training program, and host of the Vanilla JS Podcast. His developer tips newsletter is read by thousands of developers each weekday.

He’s taught developers at organizations like Chobani and the Boston Globe, and his JavaScript plugins have been used used by Apple and Harvard Business School. Chris Coyier, the founder of CSS-Tricks and CodePen, has described his writing as “infinitely quote-worthy.”

Chris loves pirates, puppies, and Pixar movies, and lives near horse farms in rural Massachusetts. He runs Go Make Things with Bailey Puppy, a lab-mix from Tennessee.

More articles by Chris




edu

Poll power: the Voter Education Project and the movement for the ballot in the American South / Evan Faulkenbury

Dewey Library - JK2160.F38 2019




edu

Tamil Nadu: Jayalalithaa slams centre for reducing allocation

TN CM Jayalalithaa charged and accused the Centre of not acting with responsibility.




edu

Singur Redux: Co pulls out of Haldia




edu

Mamata’s Bengal to introduce bill for reservation in higher education




edu

Trying to make procedures transparent, simpler: Mamata tells industrialists



  • DO NOT USE West Bengal
  • India

edu

10 positive cases with Koyambedu links emerge in Chittoor district

Most of them are involved in transporting vegetables to the Chennai market




edu

136 JSJ TrackingJS with Eduardo Lundgren

The panelists discuss TrackingJS with Eduardo Lundgren.




edu

178 JSJ Tech Education and The Business of Running Front End Masters with Marc Grabanski

03:01 - Marc Grabanski Introduction

03:35 - The jQuery UI Datepicker

04:29 - Frontend Masters

07:26 - The Live Streaming Phenomenon

09:17 - Scalability

11:25 - Value, Feedback Cycle

14:43 - Structuring Courses and Workshops

16:09 - Online vs In-Person

  • Prerequisites

18:11 - Booking Workshops

19:02 - Scaling (Cont’d)

20:00 - Online Education (eLearning) in General

21:40 - The Business Model

  • Licensing

24:12 - Hot Sellers

25:28 - Technical Setup

27:27 - Selecting Topics

29:41 - Future Topics / Topics in Production

30:38 - Individual / Company Attendees

31:45 - Upcoming Plans for Frontend Masters

32:32 - Advice For Starting Something Like Frontend Masters

34:23 - Keeping Content Up-to-date

36:14 - eLearning Experiments

39:30 - Giveaways

40:07 - Getting Started with Programming

43:03 - Marketing

45:20 - Teacher Compensation

Picks

Jessica Kerr: Functional Principles In React @ React Rally 2015 (Jamison)
thought-haver (Jamison)
[Frontend Masters] Angular Application Development (Aimee)
[Frontend Masters] JavaScript the Good Parts (Aimee)
LÄRABAR (Aimee)
Taking time off (Chuck)

The Man from U.N.C.L.E. (Joe)
BB-8 by Sphero (Joe)
ng-conf (Joe)
The Tim Ferriss Show (Marc)
CodeCombat (Marc)
Untrusted (Marc)




edu

179 JSJ redux and React with Dan Abramov

02:25 - Dan Abramov Introduction

02:43 - Dan’s Background and Journey Into Building Stuff with React

05:48 - redux and React    

10:07- The Elm Programming Language

12:19 - Reducers

14:04 - Hot Reloading

17:50 - “React makes you a better JavaScript developer.”

22:10 - Time Travel

28:26 - Storing Data and Managing State

34:43 - [Patreon] Support Dan Abramov Creating Redux and React Hot Loader

36:24 - react-transform

41:34 - Using redux outside React

43:52 - Editors and Programmer Productivity

45:35 - Future Plans

Picks

The OAuth2 RFC (Aimee)
Michael Ries: Hiring Apprentices (Jamison)
@sebmck: "Sometimes having email history isn't always a good thing..." (Jamison)
Metal Gear Solid 5: The Phantom Pain (Jamison)
Firefly (Joe)
The Elm Programming Language (Joe)
Google Keep (Dave)
15 Minute Podcast Listener chat with Charles Wood (Chuck)
Pebble Time (Chuck)
100 Days of Burpees (Chuck)
Broad City (Dan)
Jamie xx: In Colour (Dan)
Cycle.js (Dan)




edu

MJS 126: Eduardo San Martin Morote

In this episode of My JavaScript Story is Charles talks to Eduardo San Martin Morote. Eduardo is a freelance developer, a core team member of Vue.js, and loves contributing to open source. Eduardo started web development with games. He then majored in Computer Science and Mathematics.

Eduardo works as a freelancer so he can work on Open Source projects in his free time. One of the problems he draws attention to is the sustainability of Open Source Projects. The developers that maintain the projects on Open Source are not funded, and even though many companies use Open Source code they don't have sponsor it even though they have the financial means to do so.

Charles Max Wood recommends another podcast Devchat.tv hosts, Sustain Our Software that addresses this problem among others for Open Source.

Eduardo and Charles talk about characters that have accents that have to be encoded and how they deal with this problem. Eduardo then talks about some of the projects he is working on currently with Vue.js.

Sponsors

Host: Charles Max Wood

Joined by Special Guest: Eduardo San Martin Morote

Links

Picks

Eduardo San Martin Morote

Charles Max Wood




edu

Youth and higher education in Africa [electronic resource] : the cases of Cameroon, South Africa, Eritrea, and Zimbabwe / edited by Donald P. Chimanikire




edu

Youth development and critical education [electronic resource] : the promise of democratic action / Richard D. Lakes

Lakes, Richard D




edu

[ASAP] Reduction of Optical Gain Threshold in CsPbI<sub>3</sub> Nanocrystals Achieved by Generation of Asymmetric Hot-Biexcitons

Nano Letters
DOI: 10.1021/acs.nanolett.0c01079




edu

Ecological processes at marine fronts : oases in the ocean / Eduardo Marcelo Acha, Alberto Piola, Oscar Iribarne, Hermes Mianzan

Acha, Eduardo Marcelo




edu

Conservation education and outreach techniques / Susan K. Jacobson, Mallory D. McDuff, and Martha C. Monroe

Jacobson, Susan Kay, author




edu

Marine pollution and climate change / editors, Andrés Hugo Arias and Jorge Eduardo Marcovecchio




edu

Practical evaluation for conservation education and outreach : assessing impacts & enhancing effectiveness / Katherine Clavijo and Kathayoon A. Khalil ; foreword by Judy Diamond

Clavijo, Katherine, author




edu

Association Between Genetically Proxied Inhibition of HMG-CoA Reductase and Epithelial Ovarian Cancer

This study uses mendelian randomization to estimate the associations between genetic variants related to reduced HMG-CoA reductase activity and epithelial ovarian cancer in the general population and in BRCA1/2 mutation carriers.




edu

[ASAP] Kinetics of the <italic toggle="yes">Trans</italic> Effect in Ruthenium Complexes Provide Insight into the Factors That Control Activity and Stability in CO<sub>2</sub> Electroreduction

Journal of the American Chemical Society
DOI: 10.1021/jacs.0c02912




edu

[ASAP] Net-Clipping: An Approach to Deduce the Topology of Metal–Organic Frameworks Built with Zigzag Ligands

Journal of the American Chemical Society
DOI: 10.1021/jacs.0c03404




edu

[ASAP] Speciation of Cu Surfaces During the Electrochemical CO Reduction Reaction

Journal of the American Chemical Society
DOI: 10.1021/jacs.0c02354




edu

[ASAP] Co-immobilization of a Rh Catalyst and a Keggin Polyoxometalate in the UiO-67 Zr-Based Metal–Organic Framework: In Depth Structural Characterization and Photocatalytic Properties for CO<sub>2</sub> Reduction

Journal of the American Chemical Society
DOI: 10.1021/jacs.0c02425




edu

Green synthetic processes and procedures / edited by Roberto Ballini

Online Resource




edu

Flow chemistry: integrated approaches for practical applications / edited by Santiago V. Luis, Eduardo Garcia-Verdugo

Online Resource




edu

Richard Hooker, beyond certainty / Andrea Russell (the Queen's Foundation for Ecumenical Theological Education, Birmingham, UK)

Russell, Andrea, author




edu

Polypyrrole modified magnetic reduced graphene oxide composites: synthesis, characterization and application for selective lead adsorption

RSC Adv., 2020, 10,17524-17533
DOI: 10.1039/D0RA01546F, Paper
Open Access
Zhanmeng Liu, Zhimin Gao, Lichun Xu, Fengping Hu
Compared to Fe3O4/rGO, the PPy-FG composites showed desirable adsorption capacity and selectivity for Pb(II) from water.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Europium oxide nanorod-reduced graphene oxide nanocomposites towards supercapacitors

RSC Adv., 2020, 10,17543-17551
DOI: 10.1039/C9RA11012G, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Parisa Aryanrad, Hamid Reza Naderi, Elmira Kohan, Mohammad Reza Ganjali, Masoud Baghernejad, Amin Shiralizadeh Dezfuli
Fast charge/discharge cycles are necessary for supercapacitors applied in vehicles including, buses, cars and elevators.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Electrochemical reduction of CO2 to ethylene on Cu/CuxO-GO composites in aqueous solution

RSC Adv., 2020, 10,17572-17581
DOI: 10.1039/D0RA02754E, Paper
Open Access
  This article is licensed under a Creative Commons Attribution 3.0 Unported Licence.
Nusrat Rashid, Mohsin Ahmad Bhat, U. K. Goutam, Pravin Popinand Ingole
Herein, we present fabrication of graphene oxide supported Cu/CuxO nano-electrodeposits which efficiently and selectively can electroreduce CO2 into ethylene with a faradaic efficiency of 34% and conversion rate of 194 mmol g−1 h−1 at −0.985 V vs. RHE.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Nitrogen-doped RuS2 nanoparticles containing in situ reduced Ru as an efficient electrocatalyst for hydrogen evolution

RSC Adv., 2020, 10,17862-17868
DOI: 10.1039/D0RA02530E, Paper
Open Access
Yan Xu, Xiaoping Gao, Jingyan Zhang, Daqiang Gao
The reasonable design that N-doping and in situ reduced Ru metal enhances the performance of N-RuS2/Ru for HER.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Redux modules and code-splitting

Twitter Lite uses Redux for state management and relies on code-splitting. However, Redux’s default API is not designed for applications that are incrementally-loaded during a user session.

This post describes how I added support for incrementally loading the Redux modules in Twitter Lite. It’s relatively straight-forward and proven in production over several years.

Redux modules

Redux modules comprise of a reducer, actions, action creators, and selectors. Organizing redux code into self-contained modules makes it possible to create APIs that don’t involve directly referencing the internal state of a reducer – this makes refactoring and testing a lot easier. (More about the concept of redux modules.)

Here’s an example of a small “redux module”.

// data/notifications/index.js

const initialState = [];
let notificationId = 0;

const createActionName = name => `app/notifications/${name}`;

// reducer
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case ADD_NOTIFICATION:
      return [...state, { ...action.payload, id: notificationId += 1 }];
    case REMOVE_NOTIFICATION:
      return state.slice(1);
    default:
      return state;
  }
}

// selectors
export const selectAllNotifications = state => state.notifications;
export const selectNextNotification = state => state.notifications[0];

// actions
export const ADD_NOTIFICATION = createActionName(ADD_NOTIFICATION);
export const REMOVE_NOTIFICATION = createActionName(REMOVE_NOTIFICATION);

// action creators
export const addNotification = payload => ({ payload, type: ADD_NOTIFICATION });
export const removeNotification = () => ({ type: REMOVE_NOTIFICATION });

This module can be used to add and select notifications. Here’s an example of how it can be used to provide props to a React component.

// components/NotificationView/connect.js

import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { removeNotification, selectNextNotification } from '../../data/notifications';

const mapStateToProps = createStructuredSelector({
  nextNotification: selectNextNotification
});
const mapDispatchToProps = { removeNotification };

export default connect(mapStateToProps, mapDispatchToProps);
// components/NotificationView/index.js

import connect from './connect';
export class NotificationView extends React.Component { /*...*/ }
export default connect(NotificationView);

This allows you to import specific modules that are responsible for modifying and querying specific parts of the overall state. This can be very useful when relying on code-splitting.

However, problems with this approach are evident once it comes to adding the reducer to a Redux store.

// data/createStore.js

import { combineReducers, createStore } from 'redux';
Import notifications from './notifications';

const initialState = /* from local storage or server */

const reducer = combineReducers({ notifications });
const store = createStore(reducer, initialState);

export default store;

You’ll notice that the notifications namespace is defined at the time the store is created, and not by the Redux module that defines the reducer. If the “notifications” reducer name is changed in createStore, all the selectors in the “notifications” Redux module no longer work. Worse, every Redux module needs to be imported in the createStore file before it can be added to the store’s reducer. This doesn’t scale and isn’t good for large apps that rely on code-splitting to incrementally load modules. A large app could have dozens of Redux modules, many of which are only used by a few components and unnecessary for initial render.

Both of these issues can be avoided by introducing a Redux reducer registry.

Redux reducer registry

The reducer registry enables Redux reducers to be added to the store’s reducer after the store has been created. This allows Redux modules to be loaded on-demand, without requiring all Redux modules to be bundled in the main chunk for the store to correctly initialize.

// data/reducerRegistry.js

export class ReducerRegistry {
  constructor() {
    this._emitChange = null;
    this._reducers = {};
  }

  getReducers() {
    return { ...this._reducers };
  }

  register(name, reducer) {
    this._reducers = { ...this._reducers, [name]: reducer };
    if (this._emitChange) {
      this._emitChange(this.getReducers());
    }
  }

  setChangeListener(listener) {
    this._emitChange = listener;
  }
}

const reducerRegistry = new ReducerRegistry();
export default reducerRegistry;

Each Redux module can now register itself and define its own reducer name.

// data/notifications/index.js

import reducerRegistry from '../reducerRegistry';

const initialState = [];
let notificationId = 0;

const reducerName = 'notifications';

const createActionName = name => `app/${reducerName}/${name}`;

// reducer
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case ADD_NOTIFICATION:
      return [...state, { ...action.payload, id: notificationId += 1 }];
    case REMOVE_NOTIFICATION:
      return state.slice(1);
    default:
      return state;
  }
}

reducerRegistry.register(reducerName, reducer);

// selectors
export const selectAllNotifications = state => state[reducerName];
export const selectNextNotification = state => state[reducerName][0];

// actions
export const ADD_NOTIFICATION = createActionName(ADD_NOTIFICATION);
export const REMOVE_NOTIFICATION = createActionName(REMOVE_NOTIFICATION);

// action creators
export const addNotification = payload => ({ payload, type: ADD_NOTIFICATION });
export const removeNotification = () => ({ type: REMOVE_NOTIFICATION });

Next, we need to replace the store’s combined reducer whenever a new reducer is registered (e.g., after loading an on-demand chunk). This is complicated slightly by the need to preserve initial state that may have been created by reducers that aren’t yet loaded on the client. By default, once an action is dispatched, Redux will throw away state that is not tied to a known reducer. To avoid that, reducer stubs are created to preserve the state.

// data/createStore.js

import { combineReducers, createStore } from 'redux';
import reducerRegistry from './reducerRegistry';

const initialState = /* from local storage or server */

// Preserve initial state for not-yet-loaded reducers
const combine = (reducers) => {
  const reducerNames = Object.keys(reducers);
  Object.keys(initialState).forEach(item => {
    if (reducerNames.indexOf(item) === -1) {
      reducers[item] = (state = null) => state;
    }
  });
  return combineReducers(reducers);
};

const reducer = combine(reducerRegistry.getReducers());
const store = createStore(reducer, initialState);

// Replace the store's reducer whenever a new reducer is registered.
reducerRegistry.setChangeListener(reducers => {
  store.replaceReducer(combine(reducers));
});

export default store;

Managing the Redux store’s reducer with a registry should help you better code-split your application and modularize your state management.




edu

Working with mindfulness [electronic resource] : mindfulness, work, and stress reduction / a conversation with Mirabai Bush and George Kohlrieser

Bush, Mirabai, 1939- author




edu

Making Education [electronic resource] : Material School Design and Educational Governance







edu

Indian-American Renu Khator to head US council on education



  • DO NOT USE Indians Abroad
  • World

edu

Efficient CO2 electroreduction to CO at low overpotentials using a surface-reconstructed and N-coordinated Zn electrocatalyst

Dalton Trans., 2020, 49,5434-5439
DOI: 10.1039/D0DT00800A, Communication
Wanan Deng, Shixiong Min, Fang Wang, Zhengguo Zhang, Chao Kong
A surface-reconstructed and N-coordinated Zn electrocatalyst exhibits enhanced activity and selectivity for CO2 electroreduction to CO at reduced overpotentials.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Photo-reduction enables catalyst regeneration in Fenton reaction on an Fe2O3-decorated TiO2 nanotube-based photocatalyst

Dalton Trans., 2020, Advance Article
DOI: 10.1039/D0DT00670J, Paper
Quanming Peng, Guiming Peng, Liangpeng Wu, Yaqian Chen, Bin Han, Qiucheng Su, Shijun Liu, Xinjun Li
Active Fe2+ sites of TNT(Pd)/Fe2O3 with a unique electronic structure for the Fenton reaction can be self-generated.
To cite this article before page numbers are assigned, use the DOI form of citation above.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Dehydrogenation of amines in aryl-amine functionalized pincer-like nitrogen-donor redox non-innocent ligands via ligand reduction on a Ni(II) template

Dalton Trans., 2020, Advance Article
DOI: 10.1039/D0DT00466A, Paper
Manas Khatua, Bappaditya Goswami, Subhas Samanta
A Ni(II)-template directed dehydrogenative imine formation reaction via ligand reduction leading to the formation of new pincer-like azo imine ligands is described.
To cite this article before page numbers are assigned, use the DOI form of citation above.
The content of this RSS Feed (c) The Royal Society of Chemistry




edu

Military professionalism and humanitarian law: the struggle to reduce the hazards of war / Yishai Beer

Dewey Library - KZ6396.B44 2018




edu

Language rights and the law in the European Union / Eduardo D. Faingold

Online Resource




edu

The education of Brett Kavanaugh: an investigation / Robin Pogrebin and Kate Kelly

Dewey Library - KF8745.K38 P64 2019




edu

The UN Security Council and international criminal tribunals: procedure matters / Christodoulos Kaoutzanis

Online Resource




edu

North Korean graphic novels : seduction of the innocent? / Martin Petersen

Petersen, Martin, author




edu

Understanding educator beliefs in teaching and assessing soft skills : an examination within the Malaysian public higher education sector / Wan Sofiah Meor Osman

Meor Osman, Wan Sofiah, author




edu

Law, practice and procedure of arbitration / Datuk Professor Sundra Rajoo

Rajoo, Sundra, author




edu

The seduction of the simple : insights on Singapore's future directions / Devadas Krishnadas

Krishnadas, Devadas, author




edu

Students want more climate change education. Their teachers and professors are starting to listen

Spurred by activism, educators are reworking curricula to train future generations to adapt to our changing climate




edu

Structure of active ribonucleotide reductase solved with cryo-electron microscopy

Long-awaited image of elusive disordered tail helps scientists better understand the enzyme's mechanism