React js material ui initial value equal to ""

Viewed 61

I have a select field, with topics, the topics are for example the following:

  • name -> label

  1. "" -> /
  2. "logs" -> /logs
  3. "exec" -> /exec

I would like to make sure to start the topic as a value with the name equal to "" and the label "/", that is the first one, are values ​​that I take from the db so I can't make changes.

Can you help me out?

Link: codesandbox

Code:

import React from "react";
import "./styles.css";
import { TextField, MenuItem } from "@material-ui/core";

export default function App() {
  const [state, setState] = React.useState({
    pubtopic: "",
    subscriptions: [
      {
        name: "",
        label: "/"
      },
      {
        name: "exec",
        label: "/exec"
      },
      {
        name: "log",
        label: "/log"
      }
    ]
  });

  const { pubtopic, subscriptions } = state;

  const onChange = name => ({ target: { value } }) => {
    setState(prev => ({
      ...prev,
      [name]: value
    }));
  };

  return (
    <div className="App">
      <TextField
        id="pubtopic"
        select
        label="Topic"
        placeholder="Topic"
        variant="outlined"
        value={pubtopic}
        onChange={onChange("pubtopic")}
        size="small"
        fullWidth
      >
        {subscriptions.map((el, key) => (
          <MenuItem key={key} value={el.name}>
            {el.label}
          </MenuItem>
        ))}
      </TextField>
      pubtopic: {pubtopic}
    </div>
  );
}
1 Answers

You need two additions for this to work decently:

  • You need to set the Select prop displayEmpty to true so that it will treat an empty string value as something that it should still try to display instead of treating it as meaning that nothing is selected.
  • You need to set the InputLabel prop shrink to true, so that even when the current value of the TextField is empty string it will still move the label up rather than presenting it over the top of the "/" option.

Below is a working example based on your sandbox:

import React from "react";
import "./styles.css";
import { TextField, MenuItem } from "@material-ui/core";

export default function App() {
  const [state, setState] = React.useState({
    pubtopic: "",
    subscriptions: [
      {
        name: "",
        label: "/"
      },
      {
        name: "exec",
        label: "/exec"
      },
      {
        name: "log",
        label: "/log"
      }
    ]
  });

  const { pubtopic, subscriptions } = state;

  const onChange = name => ({ target: { value } }) => {
    setState(prev => ({
      ...prev,
      [name]: value
    }));
  };

  return (
    <div className="App">
      <TextField
        id="pubtopic"
        select
        label="Topic"
        variant="outlined"
        value={pubtopic}
        onChange={onChange("pubtopic")}
        size="small"
        fullWidth
        SelectProps={{ displayEmpty: true }}
        InputLabelProps={{ shrink: true }}
      >
        {subscriptions.map((el, key) => (
          <MenuItem key={key} value={el.name}>
            {el.label}
          </MenuItem>
        ))}
      </TextField>
      pubtopic: {pubtopic}
    </div>
  );
}

Edit Select with empty value as an option

Related