Categories
React Answers

How to Change Context Value While Using the useContext React Hook?

Sometimes, we want to change context value while using the useContext React hook.

In this article, we’ll look at how to change context value while using the useContext React hook.

Change Context Value While Using the useContext React Hook

We can pass in the state change function to the context to let us call them anywhere.

This way, we can change the value in whatever component that receives the context.

For example, we can write:

const { createContext, useContext, useState } = React;

const ThemeContext = createContext({});

function Content() {
  const { style, color, toggleStyle, changeColor } = useContext(
    ThemeContext
  );

  return (
    <div>
      <p>
        {color} {style}
      </p>
      <button onClick={toggleStyle}>Change style</button>
      <button onClick={() => changeColor('green')}>Change color</button>
    </div>
  );
}

function App() {
  const [style, setStyle] = useState("light");
  const [color, setColor] = useState(true);

  function toggleStyle() {
    setStyle(style => (style === "light" ? "dark" : "light"));
  }

  function changeColor(color) {
    setColor(color);
  }

  return (
    <ThemeContext.Provider
      value={{ style, visible, toggleStyle, changeColor }}
    >
      <Content />
    </ThemeContext.Provider>
  );
}

We created the ThemeContext , which we use in the App component to get the provider and wrap that around the Content component.

Then we pass our state change functions with the state variables into the context by passing them into the object in the value prop.

Then in the Content component, we can call the toggleStyle and toggleStyle and changeColor functions to change the states in App .

We get those functions in Content with the useContext hook.

Conclusion

We can pass in the state change function to the context to let us call them anywhere.

This way, we can change the value in whatever component that receives the context.

Categories
React Answers

How to Prevent Server-Side Form Submission in a React Component?

There are several ways to prevent form submission in a React component.

If we have a button inside the form, we can make set the button’s type to be button.

For instance, we can write:

<button type="button" onClick={this.onTestClick}>click me</Button>

If we have a form submit handler function passed into the onSubmit prop;

<form onSubmit={this.onSubmit}>

then in th onSubmit method, we call preventDefault to stop the default submit behavior.

For example, we can write:

onSubmit (event) {
  event.preventDefault();
  //...
}

TypeScript Type for the Match Object

We can use the RouteComponentProps interface, which is a generic interface that provides some base members.

We can pass in our own interface to match more members if we choose.

For example, we can write:

import { BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom';

interface MatchParams {
  name: string;
}

interface MatchProps extends RouteComponentProps<MatchParams> {}

const App = () => {
  return (
    <Switch>
      <Route
         path="/products/:name"
         render={({ match }: MatchProps) => (
            <Product name={match.params.name}
         /> )}
      />
    </Switch>
  );
}

We use the MatchProps interface that we created as the type for the props parameter in the render prop.

Then we can reference match.params as we wish.

Categories
React Answers

How to Pass URL Parameters to Component with React Router?

Sometimes, we want to pass URL parameters to components with React Router.

In this article, we’ll look at how to pass URL parameters to components with React Router.

Pass URL Parameters to Component with React Router

We can pass URL parameters if we create a route that allows us to pass parameters to it.

For instance, we can write:

const App = () => {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/foo">foo</Link>
          </li>
          <li>
            <Link to="/bar">bar</Link>
          </li>
          <li>
            <Link to="/baz">baz</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/:id" children={<Child />} />
        </Switch>
      </div>
    </Router>
  );
}

function Child() {
  const { id } = useParams();

  return (
    <div>
      <h3>ID: {id}</h3>
    </div>
  );
}

We have a Child component that has the useParams hook.

It lets us get the URL parameters that we want and it’s passed in from navigation.

It returns the URL parameter as a key-value pair.

The keys are what we defined and the value is what we have passed when we navigate.

In App , we have the Link components with the paths.

And also we have the Switch components that have the route that takes the id URL parameter.

The Route has the route that we pass in. children has the component that’s displayed.

Conclusion

We can pass URL parameters if we create a route that allows us to pass parameters to it.

Categories
React Answers

How to Make GraphQL Query Requests with React Apollo?

Sometimes, we want to make GraphQL query requests with React Apollo in our React app.

In this article, we’ll look at how to make GraphQL query requests with React Apollo in our React app.

Make GraphQL Queries with React Apollo

We can make GraphQL queries with React Apollo by using the client.query method.

This is available once we update the component by calling withApollo function.

For instance, we can write:

class Foo extends React.Component {
  runQuery() {
    this.props.client.query({
      query: gql`...`,
      variables: {
        //...
      },
    });
  }

  render() {
    //...
  }
}

export default withApollo(Foo);

The client.query method will be available in the props once we call withApollo with our component to return a component.

The method takes an object that has the query and variables properties.

The query property takes a query object returned by the gql form tag.

variables has an object with variables that we interpolate in the query string.

We can also wrap our app with the ApolloConsumer component.

For example, we can write:

const App = () => (
  <ApolloConsumer>
    {client => {
      client.query({
        query: gql`...`,
        variables: {
          //...
        }
      })
    }}
  </ApolloConsumer>
)

We can make our query in here.

For function components, there’s the useApolloClient hook.

For instance, we can write:

const App = () => {
  const client = useApolloClient();
  //...
  const makeQuery = () => {
    client => {
      client.query({
        query: gql`...`,
        variables: {
          //...
        }
      })
    }
  }
  //...
}

The hook returns the client that we can use to make our query.

There’s also the useLazyQuery hook that we can use to make queries.

For instance, we can write:

const App = () => {
  const [runQuery, { called, loading, data }] = useLazyQuery(gql`...`)
  const handleClick = () => runQuery({
    variables: {
      //...
    }
  })
  //...
}

runQuery lets us make our query.

Conclusion

We can make GraphQL queries with React Apollo by using the client.query method.

This is available once we update the component by calling withApollo function.

Categories
React Answers

How to Test a React Component Function with Jest?

Sometimes, we want to test React component methods with Jest.

In this article, we’ll look at how to test React component methods with Jest.

Test a React Component Function with Jest

We can mock functions that our component depend on so that we can do testing with it.

For instance, we can write:

import React, { Component } from 'react';

class Child extends Component {
   constructor (props) {
      super(props);
   };

  render() {
      const { onSubmit, label} = this.props;
      return(
        <form  onSubmit={onSubmit}>
          <Button type='submit'>{label}</Button>
        </form >
      );
   };
};

export default class App extends Component {
  constructor (props) {
    super(props);
    this.label = “foo”;
  };

  onSubmit = (option) => {
    console.log('submitted');
  };

  render () {
    return(
      <div className="container">
        <Child label={this.label} onSubmit={this.onSubmit} />
      </div>
    );
  };
};

We can then mock the onSubmit function when we test the child by writing:

import React from 'react';
import { shallow } from 'enzyme';
import Child from '../Child';

const onSubmitSpy = jest.fn();
const onSubmit = onSubmitSpy;

const wrapper = shallow(<Child onSubmit={onSubmitSpy} />);
let container, containerButton;

describe("Child", () => {
  beforeEach(() => {
    container = wrapper.find("div");
    containerButton = container.find(“Button”);
    onSumbitSpy.mockClear();
  });

  describe("<Button> behavior", () => {
     it("should call onSubmit", () => {
       expect(onSubmitSpy).not.toHaveBeenCalled();
       containerButton.simulate(‘click’);
       expect(onSubmitSpy).toHaveBeenCalled();
     });
  });
});

We mount the component with the onSubmit prop populated by the onSubmitSpy , which is a mock function.

We tested by simulating a click event on the button of the Child component.

Then we check if the mocked function is called with toHaveBeenCalled .

Conclusion

We can mock functions that our component depend on so that we can do testing with it.