Extending an already defined component in react - reactjs

I've got a component named Button in a react library and would like to extend its capabilities furthermore. The following is the code which I wrote.
import React from 'react';
import { Button } from 'reactstrap';
export class Button extends React.Component {
render () {
return (
<Button color="primary" className="Button">primary</Button>
);
}
}
I would like to use the same name as the already defined component. The problem is, when I run the application, I get an error saying,
Uncaught Error: Module build failed: C:/Users/dimal/Documents/GitHub/theme-wso2/module/components/MaterialButton.js: Duplicate declaration "Button"
How can I import the component I would like to extend in another name? as far as I think, if I rename the component this issue would go away! Am I correct?

You can name your Button from reactstrap to a diff name. To achieve this write something similar to below
import { Button as BootStrapButton } from 'reactstrap';
Now use BootStrapButton in places where you want to use button from reactstrap.

Related

Connection between Bootstrap componments reactstrap and react.Component

I'm new to Rect. I'd like to ask perhaps a most basic question since I can't find the relavent documentation or a answer on Google.
Following is the first 3 lines of typical react code:
import React, { Component } from "react";
import {
Button,
Modal,
} from "reactstrap";
export default class CustomModal extends Component {
...
}
What is the connection between Bootstrap componments imported on the second line from reactstrap and the Component class in react(that is, react.Component)? Why a CustomModal subclass from react.Component instead of reactstrap.Modal? is react.Component a sort of abstract class and reactstrap.Modal concret class extending react.Component?
Basically, yes. You extend React.Component to create your own custom class-based React components. The others that you are importing are from libraries where the library author has already created the components. Note that you can also create custom function-based React components where you don't extend React.Component. I would recommend reading through the React.Component documentation.
To your question about how it relates to CustomModal, you would use Modal as a component within CustomModal. For example:
import React, { Component } from "react";
import {
Button,
Modal,
} from "reactstrap";
export default class CustomModal extends Component {
...
render() {
return <Modal />;
}
}
Note that this example is just to give you the idea of how to use an imported component in your own custom component. It is not necessarily how to use reactstrap.Modal itself.

How to properly import a web component to react app?

I have a catalago-component.js which is a web component. I'm trying to use this web component like so:
import React from 'react'
import './../../../assets/catalago-component'
class Loja extends React.Component{
constructor(props){
super(props)
this.state = {}
}
render(){
return(
<React.Fragment>
<div className="page-header">
<h1 className="page-title">Loja</h1>
</div>
<catalago-component></catalago-component>
</React.Fragment>
)
}
}
export default Loja
but every time I run my react app I get this error
src\assets\catalago-component.js
Line 1:1: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 1:85: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 1:399: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 1:599: Expected an assignment or function call and instead saw an expression no-unused-expressions
...
but if I do any changes to the app that makes it recompile then it works just fine
how to solve this error forever? I don't want this app breaking every time I run it for the first time
EDIT: I tried to use this web component with pure html and it worked. take a look
https://eduardopreuss.github.io/web-component/
https://github.com/eduardopreuss/web-component
EDIT 2: link to codesandbox using react + web component https://codesandbox.io/s/hopeful-cohen-ut6mv?file=/src/App.js
I think you might want to try something like this:
import Catalago from './../../../assets/catalago-component'
Then use the component like:
<Catalago></Catalago>
Assuming your Web component issomething like this:
class Catalago extends React.Component {
render() {
return <speical-web-stuff><speical-web-stuff>
}
}
See:https://reactjs.org/docs/web-components.html
As said above, you should give your component a name in order to import.
import Catalago from './../../../assets/catalago-component'
However, sth you may pay attention to.
Below syntax expect your component is written in index.js under the folder catalago-component
import Catalago from './assets/catalago-component' //component locate in file name ```index```
import Catalago from './assets/catalago-component/customizedName.js'
which type of export used in that component
import Catalago from './assets/catalago-component/customizedName.js' // exporting via ```export default``` keyword
import { Catalago } from './assets/catalago-component/customizedName.js' //exporting via ```export``` keyword
Inside your webpack.config.js add this line
Than you can use your component from anywhere inside project.
import Catalago from 'Components'
There is nothing wrong how I imported, it was a eslint error just like #tsecheukfung01 said in the comments. So I added my web component to .eslintignore file and It worked just fine.
more ways to ignore eslint errors here
The way you import your component is perfectly fine.
A web-component is nothing more than any other HTMLElement like a <div> or an <a>, meaning this is NOT a React component and cannot be imported and used as such.
Example web-component
export class MyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `My Webcomponent!`
}
static get tag() {
return 'my-component';
}
}
customElements.define(MyComponent.tag, MyComponent);
Using the above web-component would look something like:
import './../../../assets/MyComponent.js'
...
render() {
return() {
<div>
<my-component></my-component>
</div>
}
}
import Catalago from './../../../assets/catalago-component'
...
render() {
return() {
<div>
<Catalago //other props/>
</div>
}
}

Lint complains about missing prop coming from HOC

I'm using the package react-translate to localise my app.
import React from 'react';
import { translate } from 'react-translate';
class Hello extends React.Component {
render() {
return (
<div>
{this.props.t('test_string')}
</div>
);
}
}
export default translate('Hello')(Hello);
In the snippet above, translate is a High Order Component, that adds the function t to the properties of Hello.
Everything works fine but lint keeps complaining because t is not in the propTypes.
error 't' is missing in props validation react/prop-types
Is that normal? I guess I'm doing something wrong but I cannot tell what...
Edit:
As #stevejay says, I could add the t to my propTypes but I don't like this solution because - from my total ignorance in react - 1) t is not a property of the component itself, nor something I want to manually pass and 2) I have to add the property to all the models where I have already added the HOC and it seems redundant
To silence the linter, you need to just add propTypes to your Hello component:
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-translate';
class Hello extends React.Component {
...
}
Hello.propTypes = {
t: PropTypes.func.isRequired
}
Any props that a component you create uses should be declared in that way.

React JS: Reusable and modifiable ui components?

I just started working on a project and I decided to use ant design package. I want to create reusable and modifiable components. For instance, I want to create a button component and use it in entire app instead of using antd's button component directly. Therefore, if I decided to change how the button looks I will just change button component I created. So if I decided to use another ui package I just need to change button component or style of it instead of changing it in entire app. I am actually a back-end developer and do not have much knowledge on front-end. I wanna know if my approach is proper or not. I am asking because bellow code does not seem proper to me:
import React from 'react';
import { Button } from 'antd';
function myButton(props) {
return (
<Button {...props}>
{props.children}
</Button>
);
}
export default myButton;
In other files:
import { Button } from './components/button';
Instead of:
import { Button } from 'antd';
Should I use this approach in that way or extend these components without a change (or export them directly from components directory)?

Combining components to one library

Im currently creating a UI library for my react native project.
The components are separated into its own files like: Button, TextBox, Panel etc etc
So when i want to use them I do:
import Button from '../UI/button';
import TextBox from '../UI/textBox';
But how could I impletement the following call instead? Not needing to do import statetments for each specific component.
import { Button,TextBox, SomeOtherComp } from '../UI/??';
This would save a lot of typing when I want to use multiple components...
Create a file called index.js
The purpose of this file is to simple expose all available components from your library
import Button from './button';
import TextBox from './textBox';
...
module.exports = {
Button,
TextBox,
...
};
In the code that consumes your UI library, you can now import the components like this:
import { Button, TextBox, SomeOtherComp } from '../UI';
When you import a folder name, the packages will look for an index.js file and import that.
It is possible to re-export modules directly without writing duplicate code for importing and exporting:
// UI.js
export { default as Button } from './button';
export { default as TextBox } from './textBox';
Usage:
import { Button, TextBox } from './UI';

Resources