How to Build, Train and Deploy Your Own Recommender System – Part 2
We build a recommender system from the ground up with matrix factorization for implicit feedback systems. We then deploy the model to production in AWS.
React 16 introduced Context API as a means to share data among multiple components, regardless of its depth in the component hierarchy.
With the introduction of Hooks, it can effectively be used as a replacement for Redux, in cases where you don’t want to bring in an external dependency, or when the complexity of Redux makes you dizzy.
In this short article, let’s investigate why React Context did not quite work as we intended, and what we did to fix that.
Below I have created a Context Provider for our simple application. This context provides a counter and functions to increment and decrement its value. We also have a counter name and its setter. This code is also available in this Code Sandbox.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React, { useState } from "react";
const defaultValue = {
counter: 0,
incrementCounter: () => {},
decrementCounter: () => {},
name: "",
setName: () => {}
};
export const AppContext = React.createContext(defaultValue);
const AppContextProvider = (props) => {
const [counter, setCounter] = useState(0);
const [name, setName] = useState("");
return (
<AppContext.Provider
value={
counter,
incrementCounter: () => {
setCounter((ctr) => ctr + 1);
},
decrementCounter: () => {
setCounter((ctr) => (ctr > 0 ? ctr - 1 : 0));
},
name,
setName
}
>
{props.children}
</AppContext.Provider>
);
};
export default AppContextProvider;
The Context Provider is meant to wrap your consumer components with it so that the context will be made available to all components wrapped by it.
First we have a Card component that renders our card component containing our counter and buttons to increment and decrement it. The useContext call brings in AppContext into this component.
You know when a component state and props changes, the component re-renders? This is the same with components that consume a context. When the context changes, the component that consumes that context will get a re-render to give it a chance to update itself.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useContext, useEffect } from "react";
import { AppContext } from "./AppContext";
export const Card = ({ name }) => {
const context = useContext(AppContext);
useEffect(() => {
context.setName(name);
});
return (
<>
<div>{`Counter: ${context.name}`}</div>
<div>{`Counter value: ${context.counter}`}</div>
<button onClick={context.incrementCounter}>Increment</button>
<button onClick={context.decrementCounter}>Decrement</button>
</>
);
};
In the snippet below, I have wrapped each consumer component Card with our AppContextProvider. I want to create 3 counters that all point to the same global context.
However, to my surprise the code below does not work as intended. Can you guess why?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import AppContextProvider from "./AppContext";
import { Card } from "./Card";
import "./styles.css";
export default function UsingContext() {
const counters = [1, 2, 3];
return (
<div className="App">
<h1>Using React Context</h1>
{counters.map((c) => {
return (
<div key={c} className="Counter">
<AppContextProvider>
<Card name={`Counter ${c}`} />
</AppContextProvider>
</div>
);
})}
</div>
);
}
Clicking any of the Increment or Decrement button is meant to update the counters. Since all the counters are supposed to be pointing to the same context, all the counters should change together. However this isn’t what is happening.
It turns out that in the above code, we are actually creating 3 separate contexts. And useContext will get the context of the first Context provider up the hierarchy.
To fix this issue, instead of creating multiple contexts, we need to move the AppContextProvider up the tree to create the single context, effectively creating the global context that all the counters share. Like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import AppContextProvider from "./AppContext";
import { Card } from "./Card";
import "./styles.css";
export default function UsingContext() {
const counters = [1, 2, 3];
return (
<div className="App">
<h1>Using React Context</h1>
<AppContextProvider>
{counters.map((c) => {
return (
<div key={c} className="Counter">
<Card name={`Counter ${c}`} />
</div>
);
})}
</AppContextProvider>
</div>
);
}
In this post I have demonstrated how to create a Context, wrap a component hierarchy in it so that it functions as a Context Provider.
We have also seen how easy it is to consume that context from a component under that hierarchy. Once a component has been made a context consumer, that component will then get a re-render when it detects changes to the context, similar to when a state or props changes in a React component.
Care must be taken though when creating that provider. You can create multiple instances of that context, so that each instance will have its own separate state. However, if your intention is to create a Global context, create one copy of the context just like when you create a global Javascript variable.
We build a recommender system from the ground up with matrix factorization for implicit feedback systems. We then deploy the model to production in AWS.
We build a recommender system from the ground up with matrix factorization for implicit feedback systems. We put it all together with Metaflow and used Comet...
Building and maintaining a recommender system that is tuned to your business’ products or services can take great effort. The good news is that AWS can do th...
Provided in 6 weekly installments, we will cover current and relevant topics relating to ethics in data
Get your ML application to production quicker with Amazon Rekognition and AWS Amplify
(Re)Learning how to create conceptual models when building software
A scalable (and cost-effective) strategy to transition your Machine Learning project from prototype to production
An Approach to Effective and Scalable MLOps when you’re not a Giant like Google
Day 2 summary - AI/ML edition
Day 1 summary - AI/ML edition
What is Module Federation and why it’s perfect for building your Micro-frontend project
What you always wanted to know about Monorepos but were too afraid to ask
Using Github Actions as a practical (and Free*) MLOps Workflow tool for your Data Pipeline. This completes the Data Science Bootcamp Series
Final week of the General Assembly Data Science bootcamp, and the Capstone Project has been completed!
Fifth and Sixth week, and we are now working with Machine Learning algorithms and a Capstone Project update
Fourth week into the GA Data Science bootcamp, and we find out why we have to do data visualizations at all
On the third week of the GA Data Science bootcamp, we explore ideas for the Capstone Project
We explore Exploratory Data Analysis in Pandas and start thinking about the course Capstone Project
Follow along as I go through General Assembly’s 10-week Data Science Bootcamp
Updating Context will re-render context consumers, only in this example, it doesn’t
Static Site Generation, Server Side Render or Client Side Render, what’s the difference?
How to ace your Core Web Vitals without breaking the bank, hint, its FREE! With Netlify, Github and GatsbyJS.
Follow along as I implement DynamoDB Single-Table Design - find out the tools and methods I use to make the process easier, and finally the light-bulb moment...
Use DynamoDB as it was intended, now!
A GraphQL web client in ReactJS and Apollo
From source to cloud using Serverless and Github Actions
How GraphQL promotes thoughtful software development practices
Why you might not need external state management libraries anymore
My thoughts on the AWS Certified Developer - Associate Exam, is it worth the effort?
Running Lighthouse on this blog to identify opportunities for improvement
Use the power of influence to move people even without a title
Real world case studies on effects of improving website performance
Speeding up your site is easy if you know what to focus on. Follow along as I explore the performance optimization maze, and find 3 awesome tips inside (plus...
Tools for identifying performance gaps and formulating your performance budget
Why web performance matters and what that means to your bottom line
How to easily clear your Redis cache remotely from a Windows machine with Powershell
Trials with Docker and Umbraco for building a portable development environment, plus find 4 handy tips inside!
How to create a low cost, highly available CDN solution for your image handling needs in no time at all.
What is the BFF pattern and why you need it.