{"id":17462319,"url":"https://github.com/shaunevening/hoc-talk-slides","last_synced_at":"2026-05-04T20:36:51.745Z","repository":{"id":70528707,"uuid":"117757227","full_name":"ShaunEvening/hoc-talk-slides","owner":"ShaunEvening","description":"Slides for teaching Higher Order Components:","archived":false,"fork":false,"pushed_at":"2018-03-23T15:51:19.000Z","size":1948,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-08T05:47:06.004Z","etag":null,"topics":["higher-order-component","react","react-native","recompose"],"latest_commit_sha":null,"homepage":"http://shaunlloyd.higher-order-components.surge.sh","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ShaunEvening.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2018-01-16T23:48:24.000Z","updated_at":"2018-03-24T15:16:04.000Z","dependencies_parsed_at":"2023-03-09T11:30:22.120Z","dependency_job_id":null,"html_url":"https://github.com/ShaunEvening/hoc-talk-slides","commit_stats":null,"previous_names":["shaunevening/hoc-talk-slides"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ShaunEvening/hoc-talk-slides","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaunEvening%2Fhoc-talk-slides","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaunEvening%2Fhoc-talk-slides/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaunEvening%2Fhoc-talk-slides/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaunEvening%2Fhoc-talk-slides/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ShaunEvening","download_url":"https://codeload.github.com/ShaunEvening/hoc-talk-slides/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ShaunEvening%2Fhoc-talk-slides/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32624446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["higher-order-component","react","react-native","recompose"],"created_at":"2024-10-18T08:24:18.834Z","updated_at":"2026-05-04T20:36:51.707Z","avatar_url":"https://github.com/ShaunEvening.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# What are Higher Order Components\n\n### Getting Started\n\n```bash\n# Clone Repository\ngit clone https://github.com/ShaunLloyd/hoc-talk-slides.git\n\n# Move to repository directory\ncd hoc-talk-slides\n\n# Install dependencies\nyarn install\n\n# Launch application\nyarn start\n```\n\n### Navigating Slides\n\n- **Right Arrow**: Navigate to next slide\n- **Left Arrow**: Navigate to previous slide\n- **Down Arrow**: Navigate to the next portion of a code slide\n- **Up Arrow**: Navigate to the previous portion of a code slide\n\n---\n\n# Written Notes\n\nIn this talk we're going to talk about taking functional programming patterns and using them\ninside of your react projects. You may already being using these patterns and not even realize it.\n\n## Higher Order Functions\n\nA **higher order function** is a function that does at least one of the following:\n  - Take one or more function as arguments\n  - Return a Function\n\nLet's consider the following function:\n\n```js\nconst multiplyBy = (multiplier) =\u003e\n  (number) =\u003e number * multiplier;\n```\n\nHere we see `multiplyBy()` which takes a multiplier then returns a function that\ntakes `number`. The returned function returns `number` multiplied by the `multiplier` given to\n`multiplyBy()`.\n\nLet's make a function that applies the Harmonized Sales Tax (HST) of 13%. To calculate the total\nafter HST, we need to multiple the given value by 1.13.\n\n```js\nconst applyHST = multiplyBy(1.13); // returns: (number) =\u003e number * 1.13\n\napplyHST(20.99); // Returns: 23.718699999999995\n```\n\n[**Run the example here**](https://repl.it/@ShaunLloyd1/Higher-Order-Functions)\n\n## Function Composition\n\nFunction composition is the mathematical concept of taking two or more Functions\nand combining them to create a new function. Let's consider the following function:\n\n```js\nconst combineFunctions = (funcOne, funcTwo) =\u003e x =\u003e funcOne(funcTwo(x));\n```\n\n`combineFunctions()` is a function that takes two functions and returns a new function\n(I spy another Higher Order Function!). This new function takes in `x` and returns the\nresult of `f` given the result of `g` given `x`.\n\nNow let's use that to combine two functions:\n  - applyHST: takes a number and multiplies it by 1.13\n  - dollarsAsString: takes a number and formats it as a currency string\n\n```js\nconst totalAfterTaxesAsString = combineFunctions(\n  dollarsAsString,\n  applyHST,\n); // returns: (x) =\u003e dollarsAsString(applyHST(x));\n\ntotalAfterTaxesAsString(20.99); // Returns \"$ 23.72\"\n```\n\n[**Run the example here**](https://repl.it/@ShaunLloyd1/Function-Composition)\n\n## Higher Order Components\n\nSo how can we use this with react? A common way to apply these concepts is to use\n**Higher Order Components**. A **Higher Order Component** is a function that taking in a component\nand returns a new component.\n\n```js\nconst HigherOrderComponent = (Component) =\u003e (props) =\u003e (\n  \u003cComponent\n    higherOrderProp={someProp}\n    {...props}\n  /\u003e\n);\n```\n\nThis sounds fairly vague so let's look at an example that in commonly used when working with\nreact + redux. `react-redux`'s connect function.\n\n`connect()` is a **Higher Order Function** that takes two functions, `mapStateToProps` and `mapDispatchToProps`. This then returns a **Higher Order Component** that maps the desired\nstate values and dispatch actions as props to the given component.\n\n```js\nconst mapStateToProps = (state) =\u003e ({ counter: state.counter });\n\nconst mapDispatchToProps = (dispatch) =\u003e ({\n  incrementCounter: () =\u003e dispatch({ type: INCREMENT }),\n  decrementCounter: () =\u003e dispatch({ type: DECREMENT }),\n});\n\nconst connect = (mapStateToProps, mapDispatchToProps) =\u003e (\n  const stateProps = mapStateToProps(state);\n  const dispatchProps = mapDispatchToProps(store.dispatch);\n\n  return (Component) =\u003e (props) =\u003e (\n    \u003cComponents\n      {...stateProps}\n      {...dispatchProps}\n      {...props}\n    /\u003e\n  )\n);\n```\n\n`connect` has now returned a function that takes in a component and will return a new version of that component that now has access to `counter` from state and the two dispatch actions `incrementCounter` and `decrementCounter`\n\n## Composing Higher Order Components\n\nPerhaps you want to compose a bunch of **Higher Order Components** together to create\none big one. Well, `recompose` is a small react library that offers a bunch of **Higher Order Functions** to create **Higher Order Components** to use on your own components.\nIt also comes with it's own `compose()` function to combine as many of it's **Higher Order Functions** as you give it.\n\n```js\nconst compose = (...functions) =\u003e\n  functions.reduce((composed, fn) =\u003e (...args) =\u003e composed(fn(...args)));\n```\n\n### `compose()`\n\n\n`compose` is a function from the [`recompose` package](https://github.com/acdlite/recompose/blob/master/docs/API.md#compose) that takes any given number of functions and then uses reduce to compose\nthem all together. So:\n\n```js\nconst someComposedFunc = compose(a, b, c, d, e);\n\nsomeComposedFunc(1, 2, 4); // is equal to a(b(c(d(e(1, 2, 4)))));\n```\n\n### `withHandlers()`\n\n\n`withHandlers` is a function from the [`recompose` package](https://github.com/acdlite/recompose/blob/master/docs/API.md#withhandlers) that takes a handlers object where the keys are the\nname of the handler function added to the props of your component and the values are\n**Higher Order Functions** that takes the component's props and returns a function that\nnow has access to all the props available to the component.\n\nLet's consider the following:\n\n```js\nexport const CounterApp = ({ counter, incrementCounter, decrementCounter }) =\u003e (\n  \u003cdiv\u003e\n    \u003ch1\u003e{counter}\u003c/h1\u003e\n    \u003cbutton onClick={incrementCounter}\u003eIncrement\u003c/button\u003e\n    \u003cbutton onClick={decrementCounter}\u003eDecrement\u003c/button\u003e\n  \u003c/div\u003e\n);\n\nconst mapStateTopProps = (state) =\u003e ({\n  counter: state.counter\n});\n\nconst mapDispatchToProps = (dispatch) =\u003e ({\n  setCounter: (number) =\u003e dispatch({ type: 'SET_COUNTER', payload: number }),\n});\n\n// Let's use `compose` to compose the connect and withHandlers HOCs together\nexport const CounterAppContainer = compose(\n  connect(mapStateToProps, mapDispatchToProps),\n  withHandlers({\n    incrementCounter: (props) =\u003e\n      () =\u003e props.setCounter(props.counter + 1), // The component will have access to this function.\n                                                 // Not the one above that takes in props\n    decrementCounter : (props) =\u003e\n      () =\u003e props.setCounter(props.counter - 1),\n  }),\n)(CounterApp);\n```\n\nAbove we see that using `connect` we are giving `CounterAppContainer` access to\n`counter` from the store and giving it a dispatch action, `setCounter` to\nupdate `counter`.\n\nAfter that we are creating `incrementCounter` and `decrementCounter` handler functions using `withHandlers`.\n\nIn the end `CounterAppContainer` comes the `CounterApp` component with access to the redux and the handler functions created with `withHandlers`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaunevening%2Fhoc-talk-slides","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshaunevening%2Fhoc-talk-slides","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaunevening%2Fhoc-talk-slides/lists"}