React: how print conditionally - reactjs

I need to return conditionally a <Row> or </Row> if an index is 3 or multiple.
{
companyConfiguration.map((item, index) => {
return (
// here
{index%3===0 && <Row>}
<Col>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
// here
{index%3===0 && </Row>}
)
})
}
But I get Unexpected token, expected ","
Edit:
I need to close after third element, and reopen it at fourth.
Examples given doesn't work unfortunately.
Must be a thing similar to
return (
<>
{
(index % 3 == 0) ?
<Row>
<Col>
<p>{index}</p>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
:
<>
<Col>
<p>{index}</p>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
</Row>
</>
}
</>
)

This is not the correct approach. You should wrap all the related components inside your tenary operator, so the correct approach would be
{index % 3 === 0 && (
<Row>
<Col>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
</Row>
)
}
This is not e.g. like java scriptlets where you add a tag or html in general according to a variable's value - so you specify if a start tag and an end tag should be rendered at html page - so {index%3===0 && </Row>} is not correct.

also, you need to add fragments<> //some code</> to your code
{
companyConfiguration.map((item, index) => {
return (
<>
{index % 3 === 0 && (
<Row>
<Col>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
</Row>
)
}
</>
)
})
}

You can use it like this
{
companyConfiguration.map((item, index) => {
return (
<>
{
index%3 === 0 ? <Row>
<Col>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
</Row> : <Col>
<FormComponent
key={index}
field={item}
onChange={handleChange}
currentItem={{}}
/>
</Col>
}
</>
)
})
}

Related

Reacht 3 different cards next to each other

I am new in React and have a problem with my cards here. I want to show 3 cards next to each other but I get 3 same cards. In bootstrap react I Found this loop to show cards next to each other but because I am looping my cars in const cards I get now 3 same cards next to each other.
I have tried using React bootstrap cards but none of them worked.
If anyone knows how I can fix my issue it would be a great help!
Here is my code:
const cards = hasLoaded ? (
<>
{cars.results.length ? (
<InfiniteScroll
children={cars.results.map((car) => (
<Car2 key={car.id} {...car} setCars={setCars} />
))}
dataLength={cars.results.length}
loader={<Asset spinner />}
hasMore={!!cars.next}
next={() => fetchMoreData(cars, setCars)}
/>
) : (
<Container className={appStyles.Content}>
<Asset src={NoResults} message={message} />
</Container>
)}
</>
) : (
<Container className={appStyles.Content}>
<Asset spinner />
</Container>
);
return (
<Container>
<Row className="h-100">
<Col className="py-2 p-0 p-lg-2" lg={8}>
<PopularProfiles mobile />
<i className={`fas fa-search ${styles.SearchIcon}`} />
<Form
className={styles.SearchBar}
onSubmit={(event) => event.preventDefault()}
>
<Form.Control
value={query}
onChange={(event) => setQuery(event.target.value)}
type="text"
className="mr-sm-2"
placeholder="Search posts"
/>
</Form>
</Col>
</Row>
<Row>
{Array.from({ length: 3 }).map((_, idx) => (
<Col md={3}>{cards}</Col>
))}
<Col md={3} className="d-none d-lg-block p-0 p-lg-2">
<PopularProfiles />
</Col>
</Row>
</Container>
);

What is the differences using another components or putting everything inside the parent component in terms of performance optimization in Reactjs?

Are there any differences between using MethodRow or putting everything inside the parent in terms of performance optimization? In my case, if I use MethodRow, rendering time is around 15 ms. On the otherhand not using MethodRow rendering time is around 75 ms. What are the reasons for this?
// PS: Using React Profiler
return (
<Card className="mb-3" data-testid="method-card">
<Card.Header>{header}</Card.Header>
{isActive ? (
<Card.Body>
<div className="form-horizontal">
<FormHeading />
{_.map(params, (param, paramKey) => {
// #ts-ignore
const { oneOf: { type: secondType } = emptyObject } =
PluginTypes.fromString(param.type) || emptyObject
const options = transformOptions(variables, param, secondType)
const { [paramKey]: value = '' } = assignees
// around 15ms
// return (
// <MethodRow
// key={paramKey}
// paramKey={paramKey}
// param={param}
// value={value}
// options={options}
// handleReturnVariableChange={handleReturnVariableChange}
// />
// )
// around 75ms
return (
<FormGroup key={paramKey} as={Row} className="mb-2">
<Col md={6}>
<FormLabel className="fw-bold">{`${paramKey} {${param.type}}`}</FormLabel>
</Col>
<Col md={6}>
<FormSelect
placeholder="select"
size="sm"
value={value === null ? '' : value}
onChange={(event: ChangeEvent<HTMLSelectElement>) =>
handleReturnVariableChange(event.target.value, paramKey)
}
>
<option value="">select</option>
{_.map(sortOptions(options), (_unused, variable) => (
<option key={variable} value={variable}>
{variable}
</option>
))}
</FormSelect>
</Col>
</FormGroup>
)
})}
</div>
</Card.Body>
) : null}
</Card>)
const MethodRow = ({ paramKey, param, value, options, handleReturnVariableChange }: any) => {
return (
<FormGroup as={Row} className="mb-2">
<Col md={6}>
<FormLabel className="fw-bold">{`${paramKey} {${param.type}}`}</FormLabel>
</Col>
<Col md={6}>
<FormSelect
placeholder="select"
size="sm"
value={value === null ? '' : value}
onChange={(event: ChangeEvent<HTMLSelectElement>) =>
handleReturnVariableChange(event.target.value, paramKey)
}
>
<option value="">select</option>
{_.map(sortOptions(options), (_unused, variable) => (
<option key={variable} value={variable}>
{variable}
</option>
))}
</FormSelect>
</Col>
</FormGroup>
)
}

How do I pass one string of an array each time a component is rendered?

This component renders four cards for top teams in a database, they are already sorted by highest scores; I need a <p> tag that displays either "1st", "2nd", "3rd", "4th" on each one. The current code displays "1st2nd3rd4th" in the <p> tag of each card.
const seed = ["1st", "2nd", "3rd", "4th"];
const place = seed.map((seed) => seed);
const TeamCard = ({data}) => {
return (
<TeamCardStyle>
{!data && (
<Spinner />
)}
{data && data.getGroupScores && (data.getGroupScores.slice(0, 4).map((group) => (
<Row>
<Col className="teamCard mt-2 mb-2">
<Row>
<p># {place}</p>
</Row>
<Row>
<Col className="hideSmall">
<img className="mouseOn" src="../images/group.png" />
<img className="mouseOff" src="../images/groupSelected.png" />
</Col>
</Row>
<p>{group.name}</p>
</Col>
</Row>
))
)}
</TeamCardStyle>
)
}
export default TeamCard;
Happy Hacking!
You can use index from map function to get the relevant element from seed array.
const seed = ["1st", "2nd", "3rd", "4th"];
const TeamCard = ({data}) => {
return (
<TeamCardStyle>
{!data && (
<Spinner />
)}
{data && data.getGroupScores && (
data.getGroupScores.slice(0, 4).map((group, index) => {
return (
<Row>
<Col className="teamCard mt-2 mb-2">
<Row>
<p># {seed[index]}</p>
</Row>
<Row>
<Col className="hideSmall">
<img className="mouseOn" src="../images/group.png" />
<img className="mouseOff" src="../images/groupSelected.png" />
</Col>
</Row>
<p>{group.name}</p>
</Col>
</Row>
)
})
)}
</TeamCardStyle>
)
}
export default TeamCard

Increment or decrement a value in react array while mapping

export default class Cart extends Component {
constructor(props) {
super(props);
this.state = {
selectedForCart: [],
checkOut: true,
priceQuantity: undefined,
total: undefined,
};
}
render() {
return (
<div>
<NavBar />
{this.state.selectedForCart &&
this.state.selectedForCart.map((v, i) => {
return (
<Container className="mt-5" key={i}>
<Row>
<Col lg={2} md={2} sm={12}>
<p>
Price: ₹
{v.priceTaxIncluded}
</p>
<p style={{ fontSize: "10px" }}>Tax inclusive</p>
</Col>
<Col lg={2} md={2} sm={12}>
<Form.Group>
<Form.Label>Quantity</Form.Label>
<Form.Control
type="number"
placeholder="Quantity"
value={1}
onChange={(e) => {
this.setState({
priceQuantity: e.target.value
});
console.log(v.priceTaxIncluded * e.target.value);
}}
/>
</Form.Group>
</Col>
<Col lg={2} md={2} sm={12}>
{this.state.checkOut && (
<>
<p>{this.state.priceQuantity}</p>
</>
)}
</Col>
</Row>
</Container>
);
})}
<Footer />
</div>
);
}
}
Here in the above code, I'm mapping an array of items from the state object "" value. And if I increment a specific item, then that specific item's quantity only should increment. But it is not happening all items are getting incremented. And also the price should be multiplied with the incremented value and should be shown...
Thank You.
As in this image, I'm changing the quantity. But If I change the quantity of a product, then its reflecting the price for all products. As I have only one state object
You can bind the priceQuantity to input value. Then conditionally render in last column. As you are trying to print priceQuantity in last column it will show for all rows.
this.state = {
...
priceQuantity: 0,
..
};
{this.state.selectedForCart &&
this.state.selectedForCart.map((v, i) => {
return (
<Container className="mt-5" key={i}>
<Row>
<Col lg={2} md={2} sm={12}>
<p>
Price: ₹
{v.priceTaxIncluded}
</p>
<p style={{ fontSize: "10px" }}>Tax inclusive</p>
</Col>
<Col lg={2} md={2} sm={12}>
<Form.Group>
<Form.Label>Quantity</Form.Label>
<Form.Control
type="number"
placeholder="Quantity"
value={this.state.priceQuantity}
onChange={(e) => {
this.setState({
priceQuantity: e.target.value
});
console.log(v.priceTaxIncluded * e.target.value);
}}
/>
</Form.Group>
</Col>
<Col lg={2} md={2} sm={12}>
{this.state.checkOut && (
<>
<p>{this.state.priceQuantity ? v.priceTaxIncluded * this.state.priceQuantity : 0}</p>
</>
)}
</Col>
</Row>
</Container>
);
})}

When i change another form element autocomplete value automatically cleared in Formik React js

The form has two elements.
When I select autocomplete value from emal element and then try to input a text value to titl field, the autocomplete value is automatically changed to empty.
What should I do to fix this issue?
I have tried to change formik initialValues using states but it's not working.
sorry for the language issue. Thanks in advance!
class TicketNew extends React.Component{
state = {
clearForm:false,
spinner:false,
closeForm:false,
emailsugges:[],
}
loadAlldata() {
this.setState({
spinner:false,
})
axios.post(baseUrl+'/api/load_company_list')
.then(res => {
const comanyList = res.data;
const emls = comanyList.emls.map(function(item, i){
return {
value:item.tci, title:item.tcc
}
})
this.setState({
emailsugges:emls
})
})
this.setState({
spinner:false,
})
};
componentDidMount(){
this.loadAlldata();
};
render(){
return(
<React.Fragment>
<Formik
initialValues={{ emal: "", titl: "" }}
validationSchema={formSchema}
>
{
({ errors,
touched,
handleSubmit,
isSubmitting,
handleBlur,
values,
resetForm
}) => (
<div>
<Form onSubmit={handleSubmit}>
<Card>
<CardHeader></CardHeader>
<CardBody>
<Row>
<Col md="5" sm="12">
<FormGroup row className="position-relative">
<Col md="4">
<span>Title</span>
</Col>
<Col md="8">
<Field
type="text"
name="titl"
id="titl"
className={`
form-control ${errors.titl && touched.titl && "is-invalid"}
`}
onBlur={handleBlur('titl')}
/>
{errors.titl &&
touched.titl ? (
<div className="invalid-tooltip mt-25">
{errors.titl}
</div>
) : null}
</Col>
</FormGroup>
</Col>
<Col md="2" sm="12"></Col>
<Col md="5" sm="12">
<FormGroup row className="position-relative"
style={{display:rqst!="1"?'none':''}}
>
<Col md="4">
<span>Email Address</span>
</Col>
<Col md="8">
<Field name="emal"
component={ ({field, form}) =>
<AutoComplete
type="email"
name="emal"
id="emal"
suggestions={this.state.emailsugges}
value={
this.state.emailsugges ?
this.state.emailsugges.find(option =>
option.value === field.value)
: ''}
className={`
form-control ${errors.emal && touched.emal && "is-invalid"}
`}
filterKey="title"
suggestionLimit={4}
/>}
/>
{errors.emal &&
touched.emal ? (
<div className="invalid-tooltip mt-25">
{errors.emal}
</div>
) : null}
</Col>
</FormGroup>
</Col>
</Row>
</CardBody>
</Card>
</Form>
</div>
)}
</Formik>
</React.Fragment>
)
}
};
export default TicketNew;

Resources