Cannot create custom style with React and Bootstrap - javascript

I'm using react-bootstrap NPM package to make my React components look properly. I need to customize some of them, so I'm following the official React-Bootstrap documentation, but the code throws the error index.jsx:5 Uncaught TypeError: Cannot read property 'addStyle' of undefined.
This is my custom Button component code:
import React from "react";
import Button from 'react-bootstrap/lib/Button';
import bootstrapUtils from 'react-bootstrap/lib/utils/bootstrapUtils';
bootstrapUtils.addStyle(Button, 'custom');
export default class MediaItemButton extends React.Component {
render() {
return (
<div>
<style type="text/css">{`
.btn-custom {
background-color: purple;
color: white;
}
`}</style>
<Button bsStyle="primary">Custom</Button>
</div>
);
}
}

Change to this:
import { bootstrapUtils } from 'react-bootstrap/lib/utils';

You can do this as well:
import React from "react";
import Button from 'react-bootstrap/lib/Button';
import bootstrapUtils from 'react-bootstrap/lib/utils/bootstrapUtils';
bootstrapUtils.addStyle(Button, 'custom');
export default class MediaItemButton extends React.Component {
render() {
var styles={
"backgroundColor" : "purple",
"color" : "white"
};
return (
<div>
<Button style={styles} bsStyle="primary">Custom</Button>
</div>
);
}
}

bootstrapUtils is a named export and not a default therefore you need to use {} around it.
Try using:
import { bootstrapUtils } from 'react-bootstrap/lib/utils/bootstrapUtils';

Related

How to use CSS Global Variables?

first of all thank you so much for your time.
My doubt is simple, but i couldn't find a way to get it working.
So... basically i have a '/pages/_app.js' file:
import '../public/styles/global.css';
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
A global css file '/public/styles/global.css':
:root {
--bg-color: #000;
}
A css module file '/public/styles/header.module.css':
.header {
background-color: var(--bg-color);
}
And finally a home page '/pages/index.js'that uses the css class:
import React from 'react';
import headerStyle from '../public/styles/header.module.css';
export default function Home() {
return <div className={headerStyle.header}>Test</div>;
}
I don't get an error but i didn't manage to refer to the global variables inside the css modules.
Can you guys help me with what am i doing wrong?
If the pages/ directory exists under src/ then the path to the <Home> component should be /src/pages/ and the import for the headerStyle should be the following:
import headerStyle from "../../public/styles/header.module.css";
You just need to go up one more directory.
/*
* #filename /src/pages/index.jsx
*/
import React from "react";
import headerStyle from "../../public/styles/header.module.css";
const Home = () => {
return <div className={headerStyle.header}>Test</div>;
};
export default Home;
Here is a CodeSandbox snippet to demonstrate.

ReactJS - Handle multiples exports in a file + withRouter

I'm currently working on a web project using NodeJS and ReactJS. I wanted to have two components in a single file because they will use the same pieces of information. One of the component is using withRouter to handle the "this.props.history.push". Since I don't know the syntax to deal with my 2 conditions (withRouter + double export) I'm looking for your help.
I get the error :
Failed to compile
./src/App.js
284:83-110 './components/Dnoc_cvat.js' does not contain an export named 'Dnoc_cvat_bouton_withRouter'.
And in my App.js I wrote :
import {Dnoc_cvat_bouton_withRouter} from './components/Dnoc_cvat.js'
Dnoc_cvat.js :
import React from 'react'
import {withRouter}from 'react-router-dom';
class Dnoc_cvat extends React.Component {
render() {
return(
<h3> DNOC - CVAT </h3>
)
}
}
class Dnoc_cvat_bouton extends React.Component {
constructor(props) {
super(props);
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.props.history.push('/DNOC/CVAT');
}
render() {
return(
<div className='component-button' onClick={this.handleClick} >
<p>Hello world</p>
</div>
)
}
}
module.exports={
Dnoc_cvat:Dnoc_cvat,
Dnoc_cvat_bouton_withRouter:withRouter(Dnoc_cvat_bouton)
}
module.exports works only in Node.js.
For the browser, you will need the following export syntax:
import React from 'react'
import { withRouter } from 'react-router-dom'
export class Dnoc_cvat extends React.Component {
...
}
class Dnoc_cvat_bouton extends React.Component {
...
}
export const Dnoc_cvat_bouton_withRouter = withRouter(Dnoc_cvat_bouton)

Next.js Persistent component - Youtube embed that plays even after changing page

I am trying to create a Next.js react app. One of the requirements is that a youtube player must persist when changing pages. Only issue is that I'm not sure if it's possible with the way Next works. It seems that pages will aways re-mount regardless of the structure.
Here in my app I export Index into page.js which acts as a parent component.
<Media/> //Youtube player
page.js will always remount thus the player will reload.
page.js:
import React from 'react';
import { Provider } from 'react-redux';
import { checkLang } from '../helpers/langSupport';
import { changeLang } from '../store/actions/langAction';
import store from '../store/store';
import { Router } from '../config/router';
import Media from './youtube';
import Head from './head';
import Nav from './nav';
const childPage = (ChildPage) => {
return (
class Page extends React.Component {
componentDidMount(){
this.checkLanguage()
}
checkLanguage() {
checkLang(this.props.url, (status, result) => {
if(status){
store.dispatch(changeLang(result))
}else{
Router.pushRoute('/en'+this.props.url.asPath)
}
})
}
render() {
return (
<Provider store={store}>
<div>
<Head />
<Nav />
<ChildPage {...this.props} />
<Media/>
</div>
</Provider>
)
}
}
)
}
export default childPage;
index.js:
import React from 'react';
import { connect } from 'react-redux'
import { add, minus } from '../store/actions/countAction';
import Page from '../components/page';
export class Index extends React.Component {
render() {
return (
<div>
<div className="hero">
Count: {this.props.count.count}
<br/><br/>
<button onClick={()=>this.props.dispatch(add(1))}>Add</button>
<button onClick={()=>this.props.dispatch(minus(1))}>Minus</button>
</div>
<style jsx>{`
.hero{
margin-left: 50px;
}
`}</style>
</div>
)
}
}
export default Page(connect(state=>state)(Index));
This has now been implemented as _app.js. Check out the next.js readme to learn more.
Unfortunately this is something that does not exist in Next.js yet. Though it is actively discussed and will probably be implemented in the near future.
ReactDOM.render is called on every page change, so this is not possible today.
See discussions on:
https://github.com/zeit/next.js/issues/88
https://github.com/zeit/next.js/pull/2440
https://github.com/zeit/next.js/pull/3288

Can you use es6 import alias syntax for React Components?

I'm trying to do something like the following, however it returns null:
import { Button as styledButton } from 'component-library'
then attempting to render it as:
import React, { PropTypes } from "react";
import cx from 'classNames';
import { Button as styledButton } from 'component-library';
export default class Button extends React.Component {
constructor(props){
super(props)
}
render() {
return (
<styledButton {...this.props}></styledButton>
)
}
}
The reason is, I need to import the Button component from a library, and also export a wrapper component with the same name but maintaining the functionality from the imported component. If I leave it at import { Button } from component library then of course, I get a multiple declaration error.
Any ideas?
Your syntax is valid. JSX is syntax sugar for React.createElement(type) so as long as type is a valid React type, it can be used in JSX "tags". If Button is null, your import is not correct. Maybe Button is a default export from component-library. Try:
import {default as StyledButton} from "component-library";
The other possibility is your library is using commonjs exports i.e. module.exports = foo. In this case you can import like this:
import * as componentLibrary from "component-library";
Update
Since this is a popular answer, here a few more tidbits:
export default Button -> import Button from './button'
const Button = require('./button').default
export const Button -> import { Button } from './button'
const { Button } = require('./button')
export { Button } -> import { Button } from './button'
const { Button } = require('./button')
module.exports.Button -> import { Button } from './button'
const { Button } = require('./button')
module.exports.Button = Button -> import { Button } from './button'
const { Button } = require('./button')
module.exports = Button -> import * as Button from './button'
const Button = require('./button')
Try to import this way
import {default as StyledLibrary} from 'component-library';
I suppose you export
export default StyledLibrary
Careful with capitalisation. Best to always CamelCase.
One:
import Thing from "component";
One with alias:
import {Thing as OtherThing} from "component";
One with alias plus other defaults:
import {Thing as OtherThing}, Stuff, Fluff from "component";
More detailed example
import
{Thing as StyledButton},
{Stuff as Stuffing},
{Fluff as Fluffy},
Wool,
Cotton
from "component";
User-Defined Components Must Be Capitalized
https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized
change your code to
import { Button as StyledButton } from 'component-library';
....bah...bah....bah
<StyledButton {...this.props}></StyledButton>
No idea why I am not able to alias the import;
As a work around, I ended up doing this:
import React, { PropTypes } from "react";
import * as StyledLibrary from 'component-library';
export default class Button extends React.Component {
constructor(props){
super(props)
}
render() {
return (
<StyledLibrary.Button {...this.props}></StyledLibrary.Button>
)
}
}
Thanks all
note that when you capitalized StyledLibrary and it worked
whereas, in the original question, you did not capitalize styledButton and it did not work
both of these are the expected results with React
so you didn't discover a workaround, you simply discovered the (documented) React way of doing things

How to override className on extended component?

I am trying to position this component differently on a certain page. But when I provide it with another className property it is only using the original class's styling that was provided when declaring the component.
Component:
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
return (
<div className={styles.labelClass} />
);
}
}
export default Label;
Page where I want to position it differently:
import React, { Component } from 'react';
import styles from './page.css';
import Label from '../common/label.jsx';
class Page extends Component {
render() {
return (
<div>
<Label className={styles.positionLeft} />
</div>
);
}
}
export default Page;
Normally I would do this with custom styling but I have to use media
queries so this isn't possible in this situation.
Since <Label> is a custom component, you can to manually pass the className prop down.
This is a good use case for default props!
class Label extends Component {
render() {
return (
<div className={this.props.className} />
);
}
}
Label.defaultProps = {
className: styles.labelClass
}
That way, if no className is provided to Label, it will use the labelClass style, otherwise, it will use the prop.
I fixed it by adding another optional property customClass to the component.
Label
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
return (
<div className={styles.labelClass + ' ' + this.props.customClass} />
);
}
}
export default Label;
Page
import React, { Component } from 'react';
import styles from './page.css';
import Label from '../common/label.jsx';
class Page extends Component {
render() {
return (
<div>
<Label customClass={styles.positionLeft} />
</div>
);
}
}
export default Page;
You need to explicitly reference the className property from Label's props - try:
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
let { className } = this.props
if (!className) {
className = styles.labelClass
}
return (
<div className={className} />
);
}
}
export default Label;

Categories

Resources