What causes two identical div containers to display different results when navigating using a keyboard on a radio button?

How can I wrap a radio button group with a 200px width and maintain proper keyboard navigation? I noticed that when I implement a parent div using a Container component

const Container = ({ children }) => ( <div style={{ width: "200px" }}>{children}</div>);
, the keyboard navigation stops working properly after moving to a different radio button. However, if I use plain HTML code
<div style={{ width: "200px"}}>
, the keyboard navigation functions correctly. Both methods seem to be semantically similar when inspected using dev tools. Can anyone shed light on why the Container component affects keyboard navigation while hardcoding in HTML does not? https://codesandbox.io/s/radio-button-example-3t8l80?file=/App.js

import { Stack, RadioButton } from "@shopify/polaris";
import { useState, useCallback } from "react";

function RadioButtonExample() {
  const [value, setValue] = useState("disabled");

  const handleChange = useCallback(
    (_checked, newValue) => setValue(newValue),
    []
  );

  const Container = ({ children }) => (
    <div style={{ width: "200px" }}>{children}</div>
  );

  return (
    <Container> // keyboard navigation doesn't work properly with this
      {/* <div style={{ width: "200px"}}> */} // keyboard navigation works fine
      <Stack vertical>
        <RadioButton
          label="Accounts are disabled"
          helpText="Customers will only be able to check out as guests."
          checked={value === "disabled"}
          id="disabled"
          name="accounts"
          onChange={handleChange}
        />
        <RadioButton
          label="Accounts are optional"
          helpText="Customers will be able to check out with a customer account or as a guest."
          id="optional"
          name="accounts"
          checked={value === "optional"}
          onChange={handleChange}
        />
      </Stack>
      {/* </div> */}
    </Container>
  );
}

export default RadioButtonExample;

Answer №1

The issue arises because the Container component is nested within the RadioButtonExample component. This causes a new instance of the Container component to be created each time there is an update to the state or props. To resolve this, it is recommended to move the Container component outside of the RadioButtonExample as shown below:

import { Stack, RadioButton } from "@shopify/polaris";
import { useState, useCallback } from "react";

const Container = ({ children }) => (
  <div style={{ width: "200px" }}>{children}</div>
);

function RadioButtonExample() {
  const [value, setValue] = useState("disabled");

  const handleChange = useCallback(
    (_checked, newValue) => setValue(newValue),
    []
  );

  return (
    <Container>
      <Stack vertical>
        <RadioButton
          label="Accounts are disabled"
          helpText="Customers will only be able to check out as guests."
          checked={value === "disabled"}
          id="disabled"
          name="accounts"
          onChange={handleChange}
        />
        <RadioButton
          label="Accounts are optional"
          helpText="Customers will be able to check out with a customer account or as a guest."
          id="optional"
          name="accounts"
          checked={value === "optional"}
          onChange={handleChange}
        />
       </Stack>
    </Container>
  );
}

export default RadioButtonExample;

An alternative approach would be to use useMemo to ensure that the container remains the same. This can be implemented like so:

const Container = useMemo(() => ({ children }) => (
    <div style={{ width: "200px" }}>{children}</div>
  ), []);

Both solutions are valid, but the first one is recommended.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Scaling back does not occur in Threejs canvas when the phone is rotated back

While using the three.js library, I encountered an issue where rotating my phone caused a component to increase in size. However, upon flipping back the phone, the component did not resize properly, resulting in distortion and part of it going off the page ...

Identify the changed field using Javascript

In my MVC application, I have a form with multiple fields that I am monitoring for changes using JavaScript. The code snippet below keeps track of any changes made in the form: var _changesMade = false; // Flag the model as changed when any other fie ...

Creating a dynamic slideshow with automated arrow navigation is simpler than you may think

I have successfully tested the slideshow and it is functioning perfectly without any issues. I would like to have a dual slideshow setup (slideshow 1 and slideshow 2) with next and previous buttons, but I am interested in adding an automatic sliding featur ...

Is there a way to extract the unicode/hex representation of a symbol from HTML using JavaScript or jQuery?

Imagine you have an element like this... <math xmlns="http://www.w3.org/1998/Math/MathML"> <mo class="symbol">α</mo> </math> Is there a method to retrieve the Unicode/hex value of alpha α, which is &#x03B1, using JavaScrip ...

The addition of days is producing an incorrect result

When extracting the date from FullCalendar and attempting to edit it, I noticed that moment.js seems to overwrite all previously saved dates. Here is an example of what's happening: var date_start = $calendar.fullCalendar('getView').start.t ...

Tips for adding styles to MUI MenuList using styled components

I have a requirement to change the background-color of the MenuItem component when its selected prop is set to true. In addition, I want to add a style to the MenuItem component when it is hovered over. How can I achieve this? import * as React from " ...

What steps can be taken to ensure this website is responsive and includes a countdown counter?

I have recently created a website (http://koulick-project.surge.sh/) as a project, but I am facing challenges in making it fully responsive. I have been able to make the headings and text responsive, however, I am struggling to make the circles for the clo ...

What is the best way to transfer PHP data to an HTML tag?

I have a growing HTML file and a separate PHP document. The PHP document is responsible for fetching subscriber numbers and viewing statistics from my YouTube channel, and I need this information to be displayed in the HTML code. Here is the PHP script: ...

I am currently working on implementing data filtering in my project. The data is being passed from a child component to a parent component as checkboxes. Can anyone guide me on how to achieve this filtering process

Below is the code I have written to filter data based on priorities (low, medium, high). The variable priorityArr is used to store the filtered data obtained from "this.data". The following code snippet is from the parent component, where "prio" is the v ...

Prevent touching the pseudo content of an element

My issue involves a toggle button component where I have utilized the ::before pseudo class to add text. The problem arises when clicking on the text within the toggle button causes the button's state to change. How can this be prevented? Here is the ...

Using Babel in conjunction with an npm package intended for React applications involves a specific set of steps and

Attempting to tackle what I thought would be a straightforward task. I have a node package that utilizes advanced JavaScript syntax. My goal is to use it as a dependency in a React project. To achieve this, I installed babel packages with --save-dev, and ...

Using the HTML attribute AUTOCOMPLETEFOR as a mandatory field

I am facing an issue with the following line of code. I have marked the field as "Required", but for some reason, it is not being enforced when running the code. The field still allows empty values. @Html.AutocompleteFor(model => model.AgenteNaviero_Co ...

How to rearrange the chosen options in an AngularJS ui-select multiple menu

Is there a way to automatically rearrange the order of selected items in AngularJS ui-select multiple? Check out this code snippet, with more examples available on ui-select github <ui-select multiple ng-model="ctrl.multipleDemo.colors" theme="bootstr ...

Problem with Layering in Javascript Canvas Game using Kinetic JS

Currently, I am attempting to replicate the game found at and delving into html5 canvas and kineticJS for my study. Here is the link to my fiddle: http://jsfiddle.net/2WRwY/7/ The issues I am facing are as follows: The tail part of the player in the f ...

Configuring the interactive background for a textbox

How can I set a background image for a textbox that is clickable? I tried using a div tag with position:absolute positioned above the textbox, and included the image within it. However, the issue is that the image appears above the text. I attempted to a ...

Looking to leverage iframes in your Javascript code?

Currently, I am implementing a JSP popup window using JavaScript with an iframe to display a table of multiple records. However, when I disable the table of multiple records, it does not prevent the onclick function (hyperlink). The code snippet is provid ...

Enhanced MUI TextField component with active cursor and focused state

When using the MUI TextField component as a single input form, I encountered an issue where the component loads with focus but no visible cursor to begin typing. To start typing, the user must click into the input field or press the tab key, which then act ...

The computed function in Vue.js fails to provide a return value

I'm currently experimenting with a basic to-do list using vue.js. My goal is to calculate the total sum of all price values within an array. I created a small function under computed, but it seems like something isn't working correctly. Here&apos ...

Using ReactJS to automatically redirect to a private route once the state has changed

I recently implemented a login route in Express, leveraging the Context API to store user ID and token generated by JSONWebToken. In order to fetch todo items for the user, a valid token is essential. This token needs to be included in the headers of API ...

What is determining the height of this grid container?

How is the height of .footer calculated in scenario #2? #1 .footer { } img { width: 100%; } <div class="footer"> <img src="https://media.istockphoto.com/photos/whole-kiwi-fruit-and-half-kiwi-fruit-on-white-picture-id834807852?k=6&m=8 ...