How to replace a React Components with another React Components? - javascript

I got something like this
<Box>
<SomethingA>
</Box
I want to replace Box.SomethingA to Box.SomethingB
<Box>
<SomethingB>
</Box>
How I can do it?

I am guessing you want to replace it after an event has occurred, for ex: button click.
You can try this:
function App(){
const [box, changeBox] = useState(true)
return(
<div>
<button onClick={()=>{changeBox(!box)}} >Click</button>
<Box>
{ box ? <SomethingA/> : <SomethingB/>}
</Box>
</div>
)
}

Related

How to add an emoji button in react?

So I already did this basically 1 year ago but I forgot how to do it, and its not working now though. Here is the LINK
basically I have a like a "smile emoji icon button" and then when I click it I will pass the emoji in my text but it giving me now an error undefined. In the link you can see that it has same thing here.
import './App.scss';
import React, { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import Picker from 'emoji-picker-react';
function App() {
const [chosenEmoji, setChosenEmoji] = useState(null);
const onEmojiClick = (event, emojiObject) => {
setChosenEmoji(emojiObject);
console.log(emojiObject)
};
return (
<div className="App">
<header className="App-header">
{/* {isLogin && user ? <LoginTrue/> : <LoginFalse/>} */}
{chosenEmoji ? (
<span>You chose: {chosenEmoji.emoji}</span>
) : (
<span>No emoji Chosen</span>
)}
<Picker onEmojiClick={onEmojiClick} />
</header>
</div>
);
}
export default App;
but the new update of emoji-picker-react did get different...Is anyone can give me an idea of it? or is there another source of importing emojis..I don't want to use Input-emoji-react its too ugly.
You may find it helpful but the way I personally did it on my project were I also used emoji-picker-react and MaterialUI is through native materialUI emoji icon button like this:
<div className="chat_footer">
{!emojiPicker ? (
<InsertEmoticonIcon onClick={() => setEmojiPicker((prev) => !prev)} />
) : (
<>
<InsertEmoticonIcon
onClick={() => setEmojiPicker((prev) => !prev)}
/>
<EmojiPicker
searchDisabled="true"
previewConfig={{ showPreview: false }}
emojiStyle="google"
onEmojiClick={(e) => setInput((input) => input + e.emoji)}
height={400}
width="40%"
/>
</>
)}
As I said, InsertEmoticonIcon is a MaterialUI icon which I import
Code sandbox link:
This link may help:
https://codesandbox.io/s/emoji-picker-react-4-forked-h846rd?file=/src/App.tsx
Onclick handler has to be Emoji and Event, not Event and then emoji

Issue with React Component

I am new to React, and am trying to call a function which acts as a component, but returns two values, one called 'render' which just returns a component wrapped in a div, and another called sliderVal, which is an internal state value of that slider. Below is code from MySlider.js
function MySlider(props) {
const [sliderVal, setSliderVal] = useState(1);
return{
render:(
<div>
<Grid container justify = "center">
<Box sx={{ width: 250 }}>
<Typography id="input-slider" gutterBottom>
{props}
</Typography>
<Slider
defaultValue={1}
valueLabelDisplay="auto"
step={1}
value={sliderVal}
marks
min={1}
max={10}
onChange={(_, newValue) => setSliderVal(newValue)}
/>
</Box>
</Grid>
</div>
),
sliderVal
}
In my App.js, I am using the following code to render two sliders, and pass their values into another component.
var {render, sliderVal} = MySlider("Number of Paragraphs");
var {render1, sliderVal1} = MySlider("Number of Words");
The first one works just fine, I can use {render} to render the slider, and {sliderVal} to access its value and pass into another component. However the 2nd one does not work and nothing renders. When I console.log render1 and sliderVal1, they are both undefined. Any insight is greatly appreciated!
The 2nd change to:
var {render:render1, sliderVal:sliderVal1} = MySlider("Number of Words");

How to validate click one per browser?

How can i reduce raiting to be able to rate only once per browser?
I need to make validation for raiting component in React where client can rate only once per browser.
Here is example of the rating component:
export default function App() {
const [value, setValue] = React.useState(0);
return (
<div>
<Box component="fieldset" mb={3} borderColor="transparent">
<Typography component="legend">Rate</Typography>
<Rating
name="pristine"
value={value}
onClick={(e) => setValue(e.target.value)}
/>
</Box>
</div>
);
}
Here is sandbox link of the component sandbox link
One possible solution you could think of is to use localStorage
For every user, who has already rate, you then store a boolean to the local storage.
Then next time, it will be validated first
Something like this:
export default function App() {
const [value, setValue] = React.useState(0);
const hasRated = localStorage.getItem("hasRated");
const handleRate = (e) => {
setValue(e.target.value);
localStorage.setItem("hasRated", true);
};
return (
<div>
<Box component="fieldset" mb={3} borderColor="transparent">
<Typography component="legend">Rate</Typography>
<Rating
disabled={hasRated}
name="pristine"
value={value}
onClick={handleRate}
/>
</Box>
</div>
);
}
Please note, that this is only a demonstrated example, so it supposes that you will need to have some improvement based on your needs
Sanbox Example:

Conditional rendering in React based on the onClick property of the IconButton component in Material UI

import "./styles.css";
import React, { useState } from "react";
import { IconButton } from "#material-ui/core";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
export default function App() {
const [expand, setExpand] = useState({
arrowA: false,
arrowB: false,
arrowC: false,
arrowD: false
});
const handleChange = (e) => {
setExpand({
...expand,
[e.currentTarget.name]: !expand.arrowA,
[e.currentTarget.name]: !expand.arrowB,
[e.currentTarget.name]: !expand.arrowC,
[e.currentTarget.name]: !expand.arrowD
});
};
return (
<div className="App">
<h1>React conditional rendering</h1>
<h2>
The component below should render if the user clicks on the arrow, and
be removed if the user clicks the arrow again.
</h2>
<h5>
This arrow should show the first part of the text.{" "}
<IconButton
variant="contained"
size="small"
color="primary"
aria-label="expand"
name="arrowA"
onClick={handleChange}
>
{<ExpandMoreIcon />}
</IconButton>
</h5>
<h5>
This arrow show the second part of the text if clicked, and be possible
to remove.
<IconButton
variant="contained"
size="small"
color="primary"
aria-label="expand"
name="arrowB"
onClick={handleChange}
>
{<ExpandMoreIcon />}
</IconButton>
</h5>
<h5>
This arrow should show the third part of the text below.{" "}
<IconButton
variant="contained"
size="small"
color="primary"
aria-label="expand"
name="arrowC"
onClick={handleChange}
>
{<ExpandMoreIcon />}
</IconButton>
</h5>
<h5>
This was really the last part.{" "}
<IconButton
variant="contained"
size="small"
color="primary"
aria-label="expand"
name="arrowD"
onClick={handleChange}
>
{<ExpandMoreIcon />}
</IconButton>
</h5>
{expand.arrowA ? (
<h2>
This is the first start of the story, let's see if we can add the
rest.
</h2>
) : null}
{expand.arrowB ? (
<h2>This is the middle part, it starts to break soon.</h2>
) : null}
{expand.arrowC ? (
<h2>
We are nearing the end. But as you see, this state management is not
optimal.
</h2>
) : null}
{expand.arrowD ? (
<h2>
This is was all I wanted to show. But why is removing this so hard?
How to make this better?
</h2>
) : null}
</div>
);
}
first of all, thanks for being here! I am a beginner in React and have a question regarding how to make my state management more optimal and better working.
I am trying to render multiple components in one React hook, to avoid having to create many different hooks. But my solution isn't working properly and not very optimal. I lack knowledge how to make the state more dynamic, but I feel I am close. Here is the example in: Code Sandbox
If you open the Code Sandbox, in the second attempt file, I am trying to set [e.currentTarget.value]: [e.currentTarget.status] to try to get the status from the IconButton, which I there store as status={!expand.checkedA} . But that isn't how React state management works apparently 😅.
Could someone enlighten me on what's best practice here? If you have a recommendation for an alternative way to conditionally render multiple components, I'd also be curious.
Cheers.
I think you're doing fine I would just change a few things to make it work:
First make the handleChange do this instead of the current code:
const handleChange = (e) => {
setExpand({
...expand,
[e.currentTarget.name]: !expand[e.currentTarget.name]
});
};
In this way you will only change the one you're clicking and the rest will stay the same.
Secondly you don't need the ternary operator in your jsx, you can use the && operator:
{expand.arrowA && (
<h2>
This is the first start of the story, let's see if we can add the
rest.
</h2>
)}
Check the forked sandbox if you have questions:
https://codesandbox.io/s/cool-fog-h7vct?file=/src/App.js:2073-2226

How do I pass a component as a prop in React and Typescript?

I am new to React and am building a tab component using Material UI's Tabs component. I'd like to place the Material UI badge component within the Tab component's label prop, but I'm not sure how to go about this.
The Tab component looks as such:
<Tab
key={i}
label={label}
{...globalTabProps}
{...tabProps}
classes={{
wrapper: cx('MuiTab-wrapper'),
}}
/>
I'm trying to add the badge as such:
const label = {
<Badge
color="primary"
className={
badgeProps.badgeContent === ''
? classNames(classes.MuiBadge, classes.MuiBadgeDotted)
: classNames(classes.MuiBadge, classes.MuiBadgeNumber)
}
badgeContent={''}
invisible={false}
{...globalBadgeProps}
{...badgeProps}
></Badge>
};
Of course, this errors out (parsing error), but I don't think this is the correct way to handle this anyway.
Would anyone be able to point me in the right direction?
Many thanks!
You should wrap it with (), like so.
const label = (
<Badge
color="primary"
className={
badgeProps.badgeContent === ''
? classNames(classes.MuiBadge, classes.MuiBadgeDotted)
: classNames(classes.MuiBadge, classes.MuiBadgeNumber)
}
badgeContent={''}
invisible={false}
{...globalBadgeProps}
{...badgeProps}
></Badge>
)
Note the () wrapping it.
Then do it like so:
<Tab
key={i}
label={label}
{...globalTabProps}
{...tabProps}
classes={{
wrapper: cx('MuiTab-wrapper'),
}}
/>
What it is done inside:
const WhateverComponent = (props) => (
<div>
...
{props.label}
</div>
);

Categories