score:12

Accepted answer

Just wrap the Select component in a div and give that div the ref.

Additionally, try to use state to record the width and define that ref-width reading logic outside of the render. Put it in componentDidMount() instead, that way we've ensured that the element has rendered to the screen and we don't need to check if ref.current is truthy.

Also you can use.clientWidth instead of .offsetWidth so that you get the actual element width, not including borders.

See working sandbox:

import React, { Component } from "react";
import { Select, MenuItem } from "@material-ui/core";

class MySelect extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: 0,
      open: false,
      width: null
    };

    this.selectRef = React.createRef();
  }

  componentDidMount() {
    const width = this.selectRef.current.clientWidth;
    this.setState(
      {
        width: width
      },
      () => console.log(this.state.width)
    );
  }

  render() {
    return (
      <div ref={this.selectRef}>
        <Select
          fullWidth
          ref={this.selectRef}
          onChange={event => {
            this.setState({
              value: event.target.value
            });
          }}
          value={this.state.value}
        >
          <MenuItem value={0}>Zero</MenuItem>
          <MenuItem value={1}>One</MenuItem>
          <MenuItem value={2}>Two</MenuItem>
          <MenuItem value={3}>Three</MenuItem>
          <MenuItem value={4}>Four</MenuItem>
        </Select>
      </div>
    );
  }
}

export default MySelect;

Related Query

More Query from same tag