i have a little question, i having use PrimeReact to develop my stuff but sometimes is quite annoying change from classcomponent to functional component, so i want to change this component to funtional, someone can help me?
import React, { Component, useState } from 'react';
import { OverlayPanel } from 'primereact/overlaypanel';
import { Button } from 'primereact/button';
class Datas extends React.Component {
render() {
return (
<div className='content-section implementation'>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => this.op.toggle(e)}
/>
<OverlayPanel ref={el => (this.op = el)}>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => (e)}
/>
</OverlayPanel>
</div>
);
}
}
export default Datas
For a component like this with only a render method translating to a functional component is simply this.
import React, { Component, useState } from 'react';
import { OverlayPanel } from 'primereact/overlaypanel';
import { Button } from 'primereact/button';
const Datas = () => {
return (
<div className='content-section implementation'>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => op.toggle(e)}
/>
<OverlayPanel ref={el => (op = el)}>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => (e)}
/>
</OverlayPanel>
</div>
);
}
export default Datas
import React, { Component, useState } from 'react';
import { OverlayPanel } from 'primereact/overlaypanel';
import { Button } from 'primereact/button';
const Datas = () => {
return (
<div className='content-section implementation'>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => this.op.toggle(e)}
/>
<OverlayPanel ref={el => (this.op = el)}>
<Button
type='button'
icon='pi pi-search'
// label='Toggle'
onClick={e => (e)}
/>
</OverlayPanel>
</div>
);
}
export default Datas
Try to use this component in VS code
Glean
Related
I have a component that I'm trying to print using react-to-print, is there any way I can print this component duplicated in one page?
here is my code:
import React, {useRef} from 'react';
import { useReactToPrint } from 'react-to-print';
import MyComponent from './myComponent';
import OtherComponent from './otherComponent';
const CreateAtt = () => {
const componentRef = useRef();
const printData = useReactToPrint({
content: () => componentRef.current,
documentTitle: 'doc',
});
return (
<>
<div className='d-flex justify-content-between'>
<div ref={componentRef}>
<MyComponent />
</div>
<OtherComponent />
</div>
<button className='btn btn-primary download-button' onClick={printData}>print</button>
</>
)
}
export default CreateAtt;
Can someone help me? I'm creating a component inside React, and I want to make it more accessible using forwardRef. In my case, I'm making a button and I'm using the button's properties, and a few more I've done to make it more dynamic.
This is a summary of my code.
export interface ButtonProps
extends React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
children?: React.ReactNode;
loading?: boolean;
}
class Button extends React.Component<ButtonProps> {
render() {
const {
...otherProps
} = this.props;
return (
<button {...(otherProps)}></button>
)
}
}
export default Button;
I tried to start something, but right away it gave an error
const ForwardedElement = React.forwardRef<ButtonProps, HTMLButtonElement> (
(props: ButtonProps, ref) => <Button {...props}/>
)
export default ForwardedElement;
I suggest you to use useImperativeHandle hook
useImperativeHandle customizes the instance value that is exposed to parent components when using ref. Let's visualize that with an example.
Here's a component as search bar
import React, {forwardRef, useImperativeHandle, useRef} from "react";
import {Form} from "reactstrap";
const SearchBar = (props, ref) => {
const buttonRef = useRef<any>();
useImperativeHandle(ref, () => ({
getCurrentValue: () => {
return buttonRef.current ? buttonRef.current["value"] : '';
},
setCurrentValue: (value) => {
if (buttonRef.current) {
buttonRef.current["value"] = value;
}
}
}));
return (
<Form className="p-3 w-100" onSubmit={(e) => props.onSubmitHandler(e)}>
<div className="form-group m-0">
<div className="input-group">
<input
type="text"
className="form-control"
placeholder="Search ..."
aria-label="Word to be searched"
ref={buttonRef}
/>
<div className="input-group-append">
<button className="btn btn-primary" type="submit">
<i className="mdi mdi-magnify" />
</button>
</div>
</div>
</div>
</Form>
);
}
export default forwardRef(SearchBar);
This is the header component in which we call our search bar component
import React, {useEffect, useRef, useState} from 'react';
import SearchBar from '../Form/Search/SearchBar';
import Router from 'next/router';
const Header = () => {
const mobileSearchRef = useRef<any>();
const [search, setSearch] = useState<any>(false);
const codeSearchHandler = (e) => {
e.preventDefault();
setSearch(!search);
if (mobileSearchRef.current) {
if (mobileSearchRef.current.getCurrentValue() == '') {
return;
}
}
Router.push({
pathname: '/search',
query: {
searchTerm: mobileSearchRef.current
? mobileSearchRef.current.getCurrentValue()
: ''
},
});
mobileSearchRef.current.setCurrentValue('');
};
return (
<React.Fragment>
<header id="page-topbar">
<div className="navbar-header">
<div className="d-flex">
<div className="dropdown d-inline-block d-lg-none ms-2">
<button
onClick={() => {
setSearch(!search);
}}
type="button"
className="btn header-item noti-icon mt-2"
id="page-header-search-dropdown"
>
<i className="mdi mdi-magnify" />
</button>
<div
className={
search
? 'dropdown-menu dropdown-menu-lg dropdown-menu-end p-0 show'
: 'dropdown-menu dropdown-menu-lg dropdown-menu-end p-0'
}
aria-labelledby="page-header-search-dropdown"
>
<SearchBar
id="headerSearchBar"
ref={mobileSearchRef}
onSubmitHandler={(e) => codeSearchHandler(e)}
/>
</div>
</div>
</div>
</div>
</header>
</React.Fragment>
);
};
export default Header;
If we look at the header component, we can see that we get the input value of search bar component using mobileSearchRef and getCurrentValue method. We can also set its value using setCurrentValue method.
You have to pass the ref aside the spread props:
export interface ButtonProps
extends React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
children?: React.ReactNode;
loading?: boolean;
ref?: React.RefObject<HTMLButtonElement>
}
class Button extends React.Component<ButtonProps> {
render() {
const {
...otherProps,
ref
} = this.props;
return (
<button {...otherProps} ref={ref}></button>
)
}
}
export default Button;
const ForwardedElement = React.forwardRef<ButtonProps, HTMLButtonElement> (
(props: ButtonProps, ref) => <Button {...props} ref={ref}/>
)
export default ForwardedElement;
now it should work, see this question
hi guys I am trying to create a react app using redux toolkit , it has add to cart functionality
when I try to pass props to parent component to child component I am getting below issue please check if you can
I am getting the below error in console
the error message in console -- 'add' is not defined
parent react component
import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { selectAddSlice } from "./features/auth/addsSlice";
import Cardshild from './Cardshild'
const Addtocart = (props) => {
return (
<div>
{selectedAdds.map((add, i) => (
<Cardshild key={i} allprops={add.allprops} />
))}
</div>
);
};
export default Addtocart;
child react component
import React from 'react'
const Cardshild = ({id, addname, price, quantity}) => {
return (
<div>
<div key={add.id}>
<div> {add.addname}</div>
<div> {add.price}</div>
<button onClick={(e) =>{ e.preventDefault(); add.quantity++ }}>+</button>
<div> {add.quantity}</div>
<button onClick={(e) =>{ e.preventDefault(); add.quantity-- }}>-</button>
</div>
</div>
)
}
export default Cardshild
below is json data and this data is in redcux also what I am trying to do is when clicking the incriment or decrement button trying to update the quantity
[
{
"addname": "normaladd",
"price": "23",
"id": "1",
"quantity":0
},
{
"addname": "advancedadd",
"price": "50",
"id": "2",
"quantity":0
},
{
"addname": "premiumadd",
"price": "100",
"id": "3",
"quantity":0
}
]
What issue?You can't just show the code and ask I have an issue, fix it for me.
Next time you should be more specified if you need helps.
I don't know the issue so I just correct the code:
In the parent
{selectedAdds.map((add, i) => (
<Cardshild key={i} allprops={add} />
))}
In the child
<div key={id}>
<div> {addname}</div>
<div> {price}</div>
<button onClick={(e) =>{ e.preventDefault(); quantity++ }}>+</button>
<div> {quantity}</div>
<button onClick={(e) =>{ e.preventDefault(); quantity-- }}>-</button>
</div>
I was trying to get data from parent to child so previously and error message was showing.
now I updated the code and it fixed the issue
below is my react component
import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { selectAddSlice } from "./features/auth/addsSlice";
import Cardshild from './Cardshild'
const Addtocart = (props) => {
return (
<div>
{selectedAdds.map((add, i) => (
<Cardshild key={i} add={add} />
))}
</div>
);
};
export default Addtocart;
below is my child component
import React, {useState} from 'react'
const Cardshild = ({add}) => {
const [amount, setamount] = useState(add.quantity)
return (
<div>
<div key={add.id}>
<div> {add.addname}</div>
<div> {add.price}</div>
<button onClick={(e) =>{ e.preventDefault(); setamount(amount + 1) }}>+</button>
<div> {amount}</div>
<button onClick={(e) =>{ e.preventDefault(); if(amount > 0){
setamount(amount - 1)
}}}>-</button>
</div>
</div>
)
}
export default Cardshild
I want to remove a component from itself. So I tried creating a function in its parent and calling it from the component
I have an array with the states and I tried unmounting by removing the component from the array.
This is the parent. unmount is the function
import React, { useEffect } from "react";
import "./list.css";
import List_item from "./listitem";
function List(prop) {
const unmount = (what_to_unmount) => {
prop.itemremove(prop.items.pop(what_to_unmount));
};
let i = 0;
if (prop.items.length === 0) {
return <div></div>;
} else {
return (
<div className="list_item">
{prop.items.map((item) => {
if (item !== "") {
return <List_item name={item} unmount={prop.unmount} />;
} else {
return <div></div>;
}
})}
</div>
);
}
}
export default List;
I want to unmount this function on a button click
import React, { useEffect } from "react";
import { useState } from "react";
import "./listitem.css";
import DeleteIcon from "#material-ui/icons/Delete";
function List_item(props) {
const [check, setcheck] = useState(false);
useEffect(() => {
let checkbox = document.getElementById(`checkbox${props.name}`);
if (checkbox.checked) {
document.getElementById(props.name).style.textDecoration = "line-through";
} else {
document.getElementById(props.name).style.textDecoration = "none";
}
});
return (
<div>
<div className="item">
<span className="text" id={`${props.name}`}>
{props.name}
</span>
<div>
|{" "}
<input
type="checkbox"
id={`checkbox${props.name}`}
checked={check}
onClick={() => setcheck(!check)}
></input>{" "}
|
<span className="delete">
<DeleteIcon
onClick={() => {
props.unmount(props.name);
}}
/>
</span>
</div>
</div>
<hr className="aitem" />
</div>
);
}
export default List_item;
But it does not work.
Please help.
Editing for clarity: I cannot figure out how to dynamically create Boostrap Components using JSX in a react app. End goal is to get the new button in the "newBtnSpace" div when the first button is clicked. I have tried using show.hide methods, but those need to be hard coded. Trying to create buttons based off an array. code:
./components/newBSBtnSpaceFunc.js
import React, { Component } from 'react'
import { Button } from 'reactstrap'
export default function NewBSBtnFunc() {
let BtnArray = ["red", "blue", "green"].map((btn) => {
return React.createElement(
Button,
{variant: 'primary'},
'New Button',
{id: "newBtn"},
btn
)
}
./components/BSBtn.js
import React, { Component } from 'react'
import { Button } from 'reactstrap'
import NewBSBtnFunc from "./NewBSBtnFunc"
export default class BSBtn extends Component {
render() {
return (
<div>
<Button onClick={NewBSBtnFunc}>Click Me</Button>
<div id="newBtnSpace"></div>
</div>
)
}
}
App.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import BSBtn from "./components/BSBtn"
function App() {
return (
<div>
<BSBtn></BSBtn>
</div>
);
}
export default App;
github link: https://github.com/mollygilbert389/testingBootstrapBtn
You can conditionally show the new button by setting a state item (in this case showNewButton) to true in the onClick of the original button.
render() {
return (
<div>
<Button onClick={() => this.setState({ showNewButton: true }))}>Click Me</Button>
<div id="newBtnSpace">{ this.state.showNewButton && <Button variant="primary" id="newBtn">New Button</Button> }</div>
</div>
)
}
PS you've already successfully worked out how to create Bootstrap buttons in jsx:
<Button onClick={NewBSBtnFunc}>Click Me</Button>
onClick does not expect a return value so returning the new button won't do anything.
The way you have things organized makes it very difficult since you can't return anything from the function, and you can't modify state from outside the class. I would suggest moving your click handler into the component and using to to modify a state value that will show the second button.
Here is my suggestion:
import React, { Component } from 'react'
import { Button } from 'reactstrap'
export default class BSBtn extends Component {
state = {show: false}
handleClick = () => {
this.setState({ show: !this.state.show })
}
render() {
return (
<div>
<Button onClick={this.handleClick}>Click Me</Button>
<div id="newBtnSpace">
{this.state.show ?
<Button variant="primary" id="newBtn">New Button</Button>
: null}
</div>
</div>
)
}
}
Updated solution to your updated question:
class BSBtn extends React.Component {
state = {
show: false,
buttons: []
}
handleClick = () => {
this.setState({ show: !this.state.show })
}
handleAdd = () => {
this.setState({ buttons: [...this.state.buttons, (this.state.buttons.length + 1)] })
}
render() {
return (
<div>
<h3>Option 1</h3>
<button onClick={this.handleClick}>Click Me</button>
<div id="newBtnSpace">
{this.state.show ? [1,2,3].map((value) => (
<div>
<button>Button {value}</button>
</div>
))
: null}
</div>
<hr/>
<div style={{ marginTop: '30px' }}>
<h3>Option 2</h3>
<button onClick={this.handleAdd}>Click Me</button>
{this.state.buttons.map((value) => (
<div>
<button>Button {value}</button>
</div>
))}
</div>
</div>
)
}
}
ReactDOM.render(<BSBtn />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />