I separate a lot of if/else components into a logical component and a render component. Now only the render components have styling, but they can share common style configuration, usually through a theme that's injected higher up (react-jss).
This keeps complexity of render components relatively smaller. I also don't mind breaking up compositional components for say NumbericInput, IntegerInput, WholePositiveInput, WholeInput, etc for form fields, each one with some entry filters in the component, and state level validation elevated to the containing component (and ultimately through form events, etc).
Beyond a lot of this, you have components with some display variances (subheaders that are shared in a given section of an application for sub-navigation, and some informative display), Most displays in the application I'm currently working on have about 5 shared higher order components (route level, header, section subheader, page footer, page capture/composition, data rendering, form input), and about 10-15 smaller/nested components just for rendering about half shared.
Across the application so far, there are about 200 components, with the application about 30% complete. The application itself is using react-jss as it's the base for styling with the material-ui component library. I've tweaked what gets placed in the theme a bit to pass additional configuration items into the theme. Portions of these additional options are part of a release configuration (per client environment/deployment), and part from flexible application options that are loaded from the API when the application loads, configurable within the application.
I've done similar things with dynamically generating base.scss files, and frankly the CSS-in-JS is far more predictable and easier to manage compared to prior applications using Bootstrap or similar SCSS/Less component baselines.