如何通过materialUI中的withStyle通过另一个元素选择器更改元素的样式

时间:2020-05-19 11:07:04

标签: reactjs material-ui

我有一个输入,当我专注于输入时,我想更改父div的边框。
https://codesandbox.io/s/jolly-fermat-e2tyo?file=/src/App.js

import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";

const InputComponent = ({ value, classes }) => (
  <div className={classes.inputContainer}>
    <input value={value} className={classes.input} />
  </div>
);

const styles = {
  input: {
    fontSize: 14,
    padding: 15,
    "&:focus": {
      backgroundColor: "#F8F8F8",
      $inputContainer: {
        //I know this won't work
        border: "1px solid #006CFF"
      }
    }
  },
  inputContainer: {
    border: "1px solid black",
    backgroundColor: "white"
  }
};

const InputWithStyles = withStyles(styles)(InputComponent);

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <InputWithStyles />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);

当前使用material-ui中的withStyles HOC,并在组件上使用props类

使用的版本:“ @ material-ui / core”:“ ^ 3.9.2”

1 个答案:

答案 0 :(得分:1)

简短的答案是,这在CSS中是不可能的(请参见Is there a CSS parent selector?)。

获得预期结果的方法是通过JavaScript更改父对象(例如,添加/删除“ focused”类)以响应focus / blur事件。这是Material-UI内部用来更改输入容器样式的方法(请参见https://github.com/mui-org/material-ui/blob/v4.9.14/packages/material-ui/src/InputBase/InputBase.js#L414)。

以下是使用此方法的沙盒修改版:

import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";
import classnames from "classnames";

const InputComponent = ({ value, classes }) => {
  const [focused, setFocused] = React.useState(false);
  return (
    <div
      className={classnames(classes.inputContainer, {
        [classes.focused]: focused
      })}
    >
      <input
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        value={value}
        className={classes.input}
      />
    </div>
  );
};

const styles = {
  input: {
    fontSize: 14,
    padding: 15,
    "&:focus": {
      backgroundColor: "#F8F8F8"
    }
  },
  inputContainer: {
    border: "1px solid black",
    backgroundColor: "white",
    "&$focused": {
      border: "1px solid #006CFF"
    }
  },
  focused: {}
};

const InputWithStyles = withStyles(styles)(InputComponent);

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <InputWithStyles />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Change input container based on input focused state

我希望看到使用Material-UI输入组件之一的示例。如果您实际上使用的是其中一种,并且为了示例简单起见将其删除,请告诉我。 Material-UI输入处理此问题的方式会有所不同-Material-UI已经在管理焦点状态的知识,因此通常不必重复该工作。相反,您只需要利用Material-UI已经添加到输入容器中的类即可。