Checkout my Getting Started with React video course on Skillshare. It is 100% free.

How to use the currentColor value in CSS

In CSS we have a special color value named currentColor that maybe be unknown to most people.

What currentColor does is to take the value for the color property and use it for any other property there has a color parameter.

For example the following:

.red-box {
    color: red;
    border: 2px solid red;
    box-shadow: 5px 10px red;
}

Is the same as having:

.red-box {
    color: red;
    border: 2px solid currentColor;
    box-shadow: 5px 10px currentColor;
}

It provides us with increased flexibility for our CSS. We just have to change the color in one place. Think of it as a CSS variable for colors only.

And it works even with inherited values too. For example:

body {
    color: blue;
}
p {
    border: 1px solid currentColor;
    // will create paragraphs with a blue border
}

Hoever, keep in mind that the rules of cascading apply also here. If we have an inherited value and we set a new color for the child, that new value will have priority.

And it works even with inherited values too. For example:

body {
    color: blue;
}
p {
    border: 1px solid currentColor;
    color: red;
    // will create paragraphs with a RED border
}

What is debouncing in Javascript

On the UI some user actions are expensive.

For example, a search operation can be expensive if we do it for every keypress. If the user types a word with 6 characters, and we search at every keyup event then we will have 6 API calls in a very short interval.

The fix would be to make the actual search only after the user had finished typing the search term. In other words, make the API call one second later after no key was pressed anymore for one second.

And this is were debouncing comes into play.

Debouncing makes sure that a function is not called again until a certain amount of time has passed without it being called.

For example, if the user is typing javascript we should search just for the jull word and not for:

  • j
  • ja
  • jav ...

Here is how one simple implementation of a debouncing function may look like:

function debounce(callback, time) {
    let interval;
    return () => {
        clearTimeout(interval)
        interval = setTimeout(() => {
                interval = null
                callback(arguments)
            }, time)
    }
}

Besides searching debouncing can be used with other expensive operations such as resizing a window, scrolling or autocomplete a text input based on an API call.

You can find here the full working example.

The double negation !! in Javascript

While working on a bug I have stumbled upon the following piece of code.

return !!(this.isFirstOverall() || this.get('videoId'));

I was super sure it is a mistake, and that was the root of the bug. It did not make any sense to negate a negation.

But after a bit of googleing I have found that there is such a thing as dobule negation in Javascript.

Long story short, its purpose is to convert any expression to an actual true/false boolean value.It is like having Boolean( insert_value_here.).

Take for example the follwoing expression:

const isIE8 = navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8);

This will log either an Array or null. And yes, we can evaluate null as being false. Actually, null is a falsely value to be more precise.

But, if we double negate this:

const isIE8 = !!navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8);

An actual true/false boolean value will be outputed.

The double negation !! is not an actual operator, like && or ||. It is just a sequence of two negation ! signs.

The first negation converts the data (whatever it data type it may be) to a boolean, but with the opposite value. The second negation changes the boolean again to give the actual result.

// example - the long version
const x = {}; // truthy
const y = !x; // false
const z = !y; // true 

// or by using the double negation
const x = {}; // truthy
const z = !!x; // true

Advantages and disadvantages of using the !! double negation in Javascript

Well, it depends on what do you want to make more clear. For sure the actual code will look strange to someone (like me 😅) who does not know about this double negation trick.

On the other side, it will provide more clear value for the actual evaluation. The result will be just true or false. For example, you will not have to wonder anymore if an empty object is considered true or false.


const result = {};
if(result) {
    // make something
}

What is box-sizing in CSS

The default way for CSS to calculate the total needed space for an element is to sum up the follwing:
totalwidth = 2*margin + 2*border-width + 2*padding + width.

The above example assumes that all of the left - right margins, paddings, and border-width are equal.

If you have a .container with the width: 100px you will not be able to put 2 .column next to each other if you have a width: 50px and a border: 1px solid red. That is because one column will have 50px + 2*1px = 52px and your container only has 100px. While I was learning CSS this was quite an "Aha!" moment for me.

.column {
    border: 1px solid red; 
    width: 50px; // will actually take 52px 
}

.container {
    width: 100px; // will not fit 2 columns
}

But you can change this behavior by setting the box-sizing property.

You can set 2 values for box-sizing:

  • content-box ; the default option
  • border-box

If we set box-sizing: border-box this means that the padding and border-width are included in the width. This can provide provides us with better control for how much space one element will take up.

So, for border-box we will have:
totalwidth = 2*margin + (width - 2*border - 2*padding).

Please note that only the border and padding are included. The margin will still add extra space.

If you want to apply it to every element on the page, out of the box, you can just set:

*, *:before, *:after {
  box-sizing: border-box;
}

Using the CSS calc() function

The calc() is a CSS function that lets you calculate values right in your CSS. For example:

.main-content {
  width: calc(100% - 40px);
}

One of the most useful features of this function is that you can mix multiple CSS units. In our example, we used a percentage with pixels. Bun we can also use units like em, pt, rem, etc.

In 90% of the cases, I find myself using calc with the substractions sign, but you can use it along with:

  • additions by using +
  • subtractions by using -
  • multiplication by using *
  • division using by /

The operator must be wrapped in white spaces. Some operators don't work well if you don't have a white a before and after it.

// use this code 
.logo {
  height: calc(4rem - 30px);
}
// instead of this one
.logo {
  height: calc(4rem-30px);
}

It is supported in all major browsers https://caniuse.com/#feat=calc.

Using calc() with CSS variables and SASS

It works out of the box with the new CSS variables:

--text-input-width: 500px;
max-width: calc(var(--text-input-width) / 2);

Using calc() in SASS or SCSS

For SASS variables you will have to interpolate the value in the calc() function:

$body_padding}: 20px;
 height: calc(100% - #{$body_padding})

JS Interview question: removing duplicates from an array

I was making a list of common interview questions for junior front-end developers. One common question that pops up quite often is how to remove duplicates from a JavaScript array.

Let's say we have to the following array:

const withDuplicates = ["dog", "cat", "dog", "cow", "dog", "cat"]

To keep just the unique values we will have:

const uniqueValues = [...new Set(withDuplicates)]
// it will return ["dog", "cat", "cow"]

Bam, that's all! Just one line!

It works as well with numeric values but does not work with objects.

The Set is a Javascript data structure and its main purpose is to be a container for data that can’t be repeated.

By initializing a Set with a destructured array (the ... operator before new Set()), we pass the actual values the Set will automatically remove the duplicates. Finally, we convert it back to an array by wrapping it into square brackets.

The Set was added in 2015 by the ES6 version of Javascript.

The old complex solution without using the ES6 Set

Before having Sets in Javascript we had to do this manually with a code similar to this one:


function remove_duplicates(arr) {
    var obj = {};
    var ret_arr = [];
    for (var i = 0; i < arr.length; i++) {
        obj[arr[i]] = true;
    }
    for (var key in obj) {
        ret_arr.push(key);
    }
    return ret_arr;
}

Introduction to React state and stateless components

If you have been learning React you would probably came across the state word being used all over the place. The heart of every component lies in its “state”! But … what is this state we keep hearing about?

What is the state in React?

The “state” is the sum of the things inside of a React Component that can change AFTER that component is built.

The state of a React component is often used with a comparison to the props of that Component. Opposite to the state, the props cannot be modified once the component is created.

Let’s take the below codesandbox. Click around on some of the buttons:

It’s a Survey app made by multiple Question components. During the execution of our survey, there are two things that may change in a Question:

  • if the buttons are disabled and
  • the text of the answer status

Both changes will take place based on one check - if the user answered the question or not.

So, a question starts with state of a null answer:

class Question extends React.Component {
    state = {
        answer: null
    };
}

And, when any of the buttons are pressed, we will set on to the state of the component the received answer.

setAnswer = (pressedButtonText) => {
    this.setState({
        answer: pressedButtonText
    });
};

//…
<button onClick={this.setAnswer.bind(this, "YES")}> YES </button>
<button onClick={this.setAnswer.bind(this, "NO")}> NO </button>

Please pay attention to the fact that, besides the initial declaration, you should always use this.setState(...) in order to change the value of the state.

And finally, the change in our state will determine the component visuals to be updated:

render() {
    // this will update the answer text
    {this.state.answer ? 
        <i>You replied with {this.state.answer} to this question.</i>: 
        <i>Please reply</i>}

    // this will update the enabled/disabled status of the buttons
    <button
        disabled={this.state.answer}
        onClick={this.setAnswer.bind(this, "YES")}
    >YES</button>
    <button
        disabled={this.state.answer}
        onClick={this.setAnswer.bind(this, "NO")}
    >NO</button>
}

On the other side, the properties will keep their value constant throughout the execution of the Survey.

You can see also in the screencast about building a React Edit Cancel Text Input component how to use the react state in order to control the way a React component behaves.

Where to Initialize State in React

There are three places where you can initialize the state of a React Component.

1. Initialize the State as a class property

This is the approach we used for our Survey example. Just set the state directly inside the Component as a class property:

class MyComponent extends React.Component {
    state = {
        isLoading: false,
        totalScore: 10 
    };
}

Setting the initial state as a class property requires the least amount of codeing?. Usually, this is the preferred way of initializing the state.

2. Initialize the State via a Constructor

Initializing state inside the constructor looks like this:

    class MyComponent extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                isLoading: false,
                totalScore: 10 
            };
    }
}

The constructor is the first method to be called when the component class is created. So, it’s the right place to initialize everything, including the state.

It is very important, when you use a constructor, to make sure that you call the parent class’ constructor: the super(props) line.

You can check this article if you want a more in-depth comparison. whether you should use a constructor or not. But the short answer is that you don’t need a constructor.

3. Initialize the React State using the getInitialState method

This way of initializing the state will only work with the when using the React.createClass from the older ES5 syntax.

var MyComponent = React.createClass({
    getInitialState() {
        return {
            isLoading: false,
            totalScore: 10 
        };
    }
});

Unless you are bound to using ES5, try to avoid it.

Stateless components

As a complementary concept to the React state is the stateless components. They are also called “Presentation only” components or “Dumb components” (maybe this is not the most polite way of referring to them).

When the sole purpose of a React Component is just to show some information, and, if that component does not change, then it means that it is a React stateless component. It does not have a state.

For example, if the scope of a Question Component is just to show the question text, then it could be written like this:

class Question extends React.Component {
    render() {
        return (
            <div className="question" style={{ borderColor: this.props.color }}>
                <b>{this.props.question}</b>
            </div>
        );
    }
}

// and to make a Question
<Question
    color="red"
    question="Was Mike Tyson one of the greatest boxers?"
/>

Furthermore, starting from React .14 we have a simpler way to write Stateless components. We can use the ES6 arrow functions and just say:

const  Question = (props)=> {
    return (
        
{props.question}
) )

Or, if we want to take advantage of the JavaScript Named Params Destructuring and the fact that the arrow functions are returning the last used statement, then we can write:

```javascript
const Question = {color, question} =>(<div className="question" style={{ borderColor: color }}>
<b>{question}</b>
</div>)



If we take a look, we managed to reduce the code of our function from 7 lines to 3. Maybe not always fewer lines of code is the same thing as a more readable code, but still, a 50% decrease in the code lines is an improvement.

Wrapping it up, I hope this small article made React state a bit more clear. As the main takeaways:
    - use the state object to control the things that will change AFTER that component is built
    - always use setState to modify the state of React Components
    - if a component is present only present information, and has no logic, then to make it a stateless component

CSS Variables explained with 5 examples

The plan for this article is to show you how native CSS variables work, and how you can use them to make your life a bit easier. As your web apps grow bigger, the CSS becomes big, redundant and many times messy. Used within a good context, the CSS variables, give you the mechanism to reuse and easily change repeatedly occurring CSS properties.

Before “the pure” CSS supporting variables, we had pre-processors like Less and Sass. But they required compiling before use, thus (sometimes), adding an extra layer of complexity.

How to define and use CSS Variables (also known as custom properties)

Let me start with something you may already be familiar with: using vars in JavaScript.

To declare a simple JavaScript var you will write something like this:

let myColor = "green";

To declare a CSS variable you will have to add a double dash before the name of that var.

body {
    --english-green-color: #1B4D3E;
}

Now, in order to use the value of the CSS variable, we can use the var(...) function.

.my-green-component{
    background-color: var(--english-green-color);
}

The easiest way to manage your CSS vars is by declaring them into the :root pseudo-class. Given the fact that the CSS variables follow the rules like any other CSS definition, having them in the :root will ensure that all selectors will gain access to these variables.

:root{
    --english-green-color: #1B4D3E;
}

Browser support for CSS variables ?

Browser support for CSS variables isn’t bad at all. If you take a look at Can I Use CSS Variables then you will see that all major browsers are supporting CSS vars out of the box. Both on mobile or desktop.

Just be careful to provide a fallback if many of your users are (still) using IE.

Let’s build stuff!

Now, let's see these CSS variables in action:

Example 1 - managing colors

By far one of the best candidates for using CSS variables are the colors of your design. Instead of copy-and-pasting the same colors over and over again, we can just place them in variables.

If somebody is asking us to update a specific shade of green or make all of the buttons red instead of blue then just change the value of that CSS variable, and that's it. You won’t have to search and replace all of the occurrences of that color.

Example 2 - removing duplicate code

Often you need to build a few different variants of components. Same base styles, just slightly different. Let's use a case with some buttons that are different in color.

The typical solution will be to create a base class, say .btn and add the variant classes.

.btn {
  border: 2px solid black;
  // more props here
}

.btn:hover {
  background: black;
  // more props here
}

.btn.red {
  border-color: red
}
.btn.red:hover {
  background: red
}

And now use them like this:

<button class="btn">Hello</button>
<button class="btn red">Hello</button>

However, this will add some code duplication. On the .red variant we have to set both the border-color and the background to red.

This can be easily fixed with a CSS variable.

.btn {
    border: 2px solid var(--color, black);
}
.btn:hover {
    background: var(--color, black);
}
.btn.red {
    --color: red
}

Example 3 - making some properties human readable

CSS vars are great to use if we want to create a shortcut to a more complex property value, so that we don't have to remember it.

CSS properties, like box-shadow, transform and font or other CSS rules with multiple parameters are perfect examples.

We can place the property in a variable so that we can reuse it via a more human readable format.

Example 4 - cascading the variables

The standard cascade rules also apply to the CSS Variables.

So, if a custom property is declared multiple times, the lowermost definition in the css file overwrites the ones above it.

The following example demonstrates how easy it is to dynamically manipulate properties on user action, while still keeping the code clear and concise.

Example 5 - Theme switcher with CSS Variables

A great thing about CSS variables is their reactive nature. As soon as we update them, whatever property has the value of the CSS variable gets updated as well. So, with just a few lines of Javascript and the smart use of CSS Variables, we can make a theme switcher mechanism.

Bonus tips for CSS Variables

Like almost all the things in CSS, the variables are also pretty straightforward and easy to use. Here are a few more tips that are not included in the examples, but are still very useful in certain situations:

  1. mind your capitalization; CSS variables are case sensitive

    :root {
     --color: blue;
     --COLOR: red;
    }
    /*--color and --COLOR are two different variables*/
  2. when you use the var() function you can send a second parameter. This value will be used if the custom property it's not found:

        width: var(--custom-width, 33%);
  3. you can use CSS variables directly into HTML

    <!--HTML-->
    <html style="--size: 600px">
    body {
      max-width: var(--size)
    }
  4. You can use a CSS variable within other CSS var:

    --base-red-color: #f00;
    --background-gradient: linear-gradient(to top, var(--base-red-color), #222);
  5. CSS variables can be made conditional with media queries. For example, the following code changes the value of the padding, based on the screen size:

    :root {
        --padding: 15px 
    }
    
    @media screen and (min-width: 750px) {
        --padding: 30px
    }
  6. Don't be afraid to use CSS variables with the calc() function.

    --text-input-width: 5000px;
    max-width: calc(var(--text-input-width) / 2);

CSS variables aren't a silver bullet. They will not fix every problem you have in the CSS realm. However, you can quickly tell they make your code more readable and maintainable.

Also, they greatly improve the ease of change across large documents. Just set all your constants in a separate file, and you won’t have to jump through thousands of lines of code when you just want to make a change to a variable.

So, what are you waiting for? Give CSS variables a try and let me know what you think.

The 7 Most Common Mistakes that beginner React Developers Make

Recently I had to hold a React workshop for some developers from a company I am working with. Some of them were juniors and others where experienced backend devs, but, to my surprise, there were some common issue patterns that kept repeating for both categories. So, I’ve decided to make a list of these common mistakes hoping it will save you some moments of frustrations when you first start to learn React:

1. Anything that it is state changing should be done via the setState method

Maybe this is an old subject, and for seasoned React developers it may be obvious but, it is still one of the most encountered issues when starting with React.

So, never ever try to do something like this:

this.state.someValue = 10

It will not work, the view will not be updated and the worst thing is that we will not get any error on the console telling us that we did something wrong.

As a general rule of thumb, always use setState when you want to change something in the state. This will ensure that the render() method is triggered and the view is updated.

this.setState({someValue:10})

2. The setState method is async

Speaking of state. - the state in React is async. It means that if we call setState, we don't have a guarantee that, when the next line is executed, the change actually took place. This can catch off guard even developers that are using React for quite some time.

If we try to use setState multiple times in the same function or code block, we may get into some strange behavior. For example, on a click handler, if we have some code like this:

doStuff = () => {
this.setState({ foo: this.state.foo + 1 });
    if (this.state.foo > 7) {
      this.setState({ bar: 20 });
    }
 }

If you use this code you will see that bar becomes 20 only when foo is 9. This is the result of the async nature of setState. When the if statement is evaluated, the setState will not have enough time to make the changes. So when foo is 8 the if statement is still evaluated as false.

In order to fix this let’s take a look at the setState documentation. We will discover a mysterious callback function that will ensure the fact that some code will be run only after setState actually makes the change. So, we can try something like this:

doStuff = () => {
   this.setState({ foo: this.state.foo + 1 }, () => {
     if (this.state.foo > 7) {
       this.setState({ bar: 20 });
     }
   });
};

And below you can see the previous example, but this time implemented with the callback function.

3. Sending props as Strings instead of Numbers

If you used to write a lot of pure HTML, you may find it natural to write something like:

<MyComponent value="2" />

However, it will send the value prop to MyComponent as a String. So, if you need it as a number, you will have to use something like parseInt. Or do it the React way: use curly brackets when sending it:

<MyComponent value={2} />

It will also work if you have to send some other javascript entities like objects or arrays:

As an alternative, you can use react props-types to define what data type a React property should be. Please note that props-type now has its own npm package.

4. Not using the right versions of what an example or a tutorial is using.

This was not directly related to the workshop, but it’s in the same category. I recently had one reader of js-craft.io emailing me and saying he is trying to follow the React API example, but for some reason, he gets some exceptions, even if the code is exactly the same. Well, it turned out that he opened an older project and tried to use the React 1.6 Context API. Meanwhile, in his package.json ,the React version was below 1.6. So, remember to check the versions from package.json 🙂 !

The following ones are still examples of what React beginners do (and from time to time we all make them), but fortunately, they are way easier to catch as they come with some errors or warnings in the console.

5. Using class instead of className

In React, if you want to assign a CSS class name to a component don’t try to do something like:

<h1 class="css-class-for-title”>Some title here</h1>

In React-JSX it will fail, as the class keyword by ES6.

Instead use className:

<h1 className="css-class-for-title”>Some title here</h1>

6. Not starting a component name with a capital letter

This one is pretty self explanatory. If you will write something like:

class myApp extends React.Component {
}

You will get a nice and beautiful: If you meant to render a React component, start its name with an uppercase letter. error. So, React components start only with a capital letter.

7. Trying to use objects with curly braces - children not accepted as object

This happens mostly to debug. When you want to show the contents of an object in React don’t expect that curly brackets in React will work similar to the standard console.log. If you will try to use curly brackets with an object you will get an error:

render() { 
  let objToPrint = {
    name:"Bob", 
    age: 5 
  } 
  return (<div>{objToPrint}</div>); 
}

If you really have to print the contents of that object then go for JSON.stringify:

render() { 
  let objToPrint = { 
    name:"Bob", 
    age: 5 
  } 
  return (<div>{JSON.stringify(objToPrint)}</div>); 
}

And as a closing thought, even if it’s not an actual mistake: try to break down and reuse components as much as possible. It's easy to write bloated components when you first start using React. Small classes/modules/whatever are easier to understand, test, and maintain, and the same is true for React components.

My mistake, when starting out with React, was under estimating just how small my components should be. Of course, the exact size will depend upon many different factors but, in general, my advice would be to make your components significantly smaller than you think they need to be.

Introduction to using GraphQl in React with Apollo

What is GraphQl and why should I be interested in it?
In a nutshell, we can see GraphQL as a syntax that describes the data you get, usually from a backend API. It was created by Facebook and in most cases, it provides good solutions to REST API's problems.

For this tutorial, the scope is to get up and running with a React application that uses Apollo to interact with a GraphQl endpoint. We will go intro more details in other articles, but for now the idea is to understand and "feel" the general workflow in GraphQl.

We will build a very simple movie application, that will interact with some data from a GraphQl endpoint. You can see it in the below image.

Installing GraphQl and Apollo

To get started we will need to add bunch of libraries to our project. If you want you can use create-react-app. Create a React app then open up a console and type:

npm i -save react-apollo graphql-tag apollo-boost

As very short run through:

  • react-apollo is the connector that links React to GraphQl. An alternative to it is Relayjs.
  • graphql-tag will be useful to write the GraphQl queries
  • and from the apollo-boost we will use the ApolloClient as the main bridge to the GraphQl endpoint

From a code perspective, we will first need to create an instance of the ApolloClient client. The ApolloClient will need the uri of the GraphQl endpoint.

import ApolloClient from "apollo-boost"

//...
const client = new ApolloClient({
  uri: "https://r9v94p7kqn.lp.gql.zone/graphql"
})

After having the ApolloClient instance ready, we will then wrap the main app content with an ApolloProvider:

import { ApolloProvider} from "react-apollo"
//...
class App extends Component {
  render() {
    return (
      <ApolloProvider client={client}>
          <Movies />
      </ApolloProvider>
    );
  }
}

Seting up a Javascript - GrapQl endpoint

You may have noticed the uri: "https://r9v94p7kqn.lp.gql.zone/graphql" from the ApolloClient constructor. If you leave out the /graphql and visit the link https://r9v94p7kqn.lp.gql.zone you will see the graphql launchpad that contains our endpoint.

Without going too deep into details our endpoint has a

  1. a schema definition that describes how a basic movie data will look like, but also what type of data the queries will return:

    // Construct a schema, using a GraphQL schema language
    const typeDefs = `
    type Query {
    allMovies: [Movie]
        movie(id: Int!): Movie
    },
    type Movie {
        id: Int
        title: String
        director: String
        actors: [String]
        poster: String
        year: Int
    }
    `;
  2. and also, a set of data + resolver functions that will be used when a query takes place:

var moviesData = [
    {
        id: 1,
        title: 'The Godfather',
        director: 'Francis Ford Coppola',
        actors: ['Marlon Brando', 'Al Pacino', 'James Caan'],
        poster: 'https://ia.media-imdb.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY268_CR3,0,182,268_AL_.jpg',
        year: 1972
      }
      //...
];

var getMovie = function(root, {id}) { 
    return moviesData.filter(m => {
        return m.id === id;
    })[0];
};

var getAllMovies = function() {
  return moviesData;
}

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    allMovies: getAllMovies,
    movie: getMovie,
  },
};

// Required: Export the GraphQL.js schema object as "schema"
export const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

In this example, we have used Javascript, but you can setup GraphQl endpoints with any major programming language. Please note, that the core data - moviesData array - should usually come from a database. We just used this static array for simplicity purposes.

Making the first GraphQl query with React - Apollo

There are multiple ways to query a GraphQl endpoint. To list the basic info of the movies we will use the Query component from react-apollo:

import { Query, ApolloProvider } from "react-apollo";
//...
const Movies = () => (
  <Query
    query={gql`
      {
        allMovies {
          id
          title
          poster
          actors
        }
      }
    `}
  >
    {({ loading, error, data }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error :(</p>;
      return data.allMovies.map(movie => (
        <div className="movie">
          <h3>{movie.title}</h3>
          <p>{JSON.stringify(movie.actors)}</p>
        </div>
      ));
    }}
  </Query>
); 

Using the parameters loading, error, data that we get access to in the child function, we can control how the layout looks like when the data is still loading or when we get an error response. At this point the complete code and app looks like this:

Triggering a GraphQl query on a React UI event

But what if we wanted to trigger a query on a specific UI event, like a button click? For example, if we wanted to get the complete details for a movie when a Get all details button is pressed.

First let's extract a Movie component:

class Movie extends Component {
  getDetails = ()=> {
   // will make the GrahQl here
  }

  render() {
    return(
        <div className="movie">
          <img src={this.props.data.poster} />
          <div className="details">
            <h3>{this.props.data.title}</h3> 
            <p>{JSON.stringify(this.props.data.actors)}</p>
            <button onClick={this.getDetails}>Get all details</button>
          </div>
        </div>
    )
  }
}

//...

const Movies = () => (
    {({ loading, error, data }) => {
    //...
return data.allMovies.map((movie) => (
<Movie key={movie.id} data={movie} />
));
    }}
);

Now, to manually trigger the GraphQl Query we will need access to the ApolloClient instance in the Movie component. All the components that are descendants of the ApolloProvider can gain access to the client instance by using the withApollo() helper function:

import { Query, ApolloProvider, withApollo} from "react-apollo";
//...
class Movie extends Component {
  //...
}
Movie = withApollo(Movie)

So now we can access the ApolloClient as a property of the Movie component, and use it to trigger the query call:

class Movie extends Component {
  getDetails = ()=> {
    this.props.client.query({
      query: gql`
        {
          movie (id:${this.props.data.id}) {
            id
            title
            director
            actors
            year
          }
        }
      `,
    }).then((data) => alert(JSON.stringify(data.data.movie,null,'\t')))
  }
  //...
}

You can play with the complete app in the bellow code sandbox:

I hope you enjoyed this article and realized is quite easy to get up and running with using GraphQl in React. This is just the tip of the iceberg, but hey ... every journey begins with a single step :).