18
9

More than 5 years have passed since last update.

Material-UIのwithStylesで指定するstylesCreatorの中で親からpropsとして受け取った値を動的に適応させるHOC

Last updated at Posted at 2018-06-19

:writing_hand: Can withStyles pass props to styles object?

Material-UIのstyleのカスタムに関しては、こちらの記事が簡潔で分かりやすいので諸々の説明は割愛。
material-uiの見た目を調整する3つの方法

setup
npx create-react-app my-app
cd my-app
yarn add @material-ui/core
touch src/button.jsx 
yarn start

初手デフォルト設定

src/button.jsx
import React, { Component } from "react";
import { withStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const styles = theme => ({});

const ExtendButton = props => {
  const { children } = props;
  return <Button variant="contained">{children}</Button>;
};

export default withStyles(styles)(ExtendButton);
src/App.js
import React, { Component } from "react";
import Button from "./button";

class App extends Component {
  render() {
    return (
      <div>
        <Button>Hello World</Button>
      </div>
    );
  }
}

export default App;

452.png

お次はデフォルト設定をハック

src/button.jsx
const styles = theme => ({
  contained: {
    backgroundColor: "green"
  }
});

const ExtendButton = props => {
  const { classes, children } = props;

  return (
    <Button
      variant="contained"
      classes={{
        contained: classes.contained
      }}
    >
      {children}
    </Button>
  );
};

747.png

すると人はこうしたくなってくる

src/App.js
 return (
      <div>
        <Button backgroundColor="green">Hello World</Button>
        <Button backgroundColor="red">Hello World</Button>
        <Button backgroundColor="blue">Hello World</Button>
      </div>
    );

そんな時はHOCの出番

今回の目玉HOCを作ってゆきます
touch src/withStylesProps.jsx
src/withStylesProps.jsx
import { withStyles } from "@material-ui/core/styles";
import * as React from "react";

const withStylesProps = styles => Component => props => {
  const Comp = withStyles(styles(props))(Component);
  return <Comp {...props} />;
};

export default withStylesProps;

最終的にこんな感じになる

src/App.js
import React, { Component } from "react";
import Button from "./button";

class App extends Component {
  render() {
    return (
      <div>
        <Button backgroundColor="green">Hello World</Button>
        <Button backgroundColor="red">Hello World</Button>
        <Button backgroundColor="blue">Hello World</Button>
      </div>
    );
  }
}

export default App;
src/button.jsx
import React, { Component } from "react";
import withStylesProps from "./withStylesProps";
import Button from "@material-ui/core/Button";

const styles = props => ({
  contained: {
    backgroundColor: props.backgroundColor
  }
});

const ExtendButton = props => {
  const { classes, children } = props;

  return (
    <Button
      variant="contained"
      classes={{
        contained: classes.contained
      }}
    >
      {children}
    </Button>
  );
};

export default withStylesProps(styles)(ExtendButton);

747.png

:moyai: 「...themeを継承できるものも用意した方がええな」

18
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
9