Somewhat new to React.
I want to be able to toggle between React elements CreateUser, EditUser, and ListUser.
It would be great to have a clickable text that when selected pulls up that element and its
corresponding stuff. In the case of Create its a field with a save button.
What is the best way to have my CrudSelector class list all three texts, make them clickable and pull up the stuff inside toggling to the selected one at a time?
Welcome. Always a good idea to share code with your question.
You'll want to use some kind of state which tells your parent component which child component to show. Kind of like this in your React functional component:
const [ featureToShow, setFeatureToShow ] = useState('list')
return (
<>
{/* Show some buttons to change the state */}
<button onClick={() => setFeatureToShow('list')}>Show User List</button>
<button onClick={() => setFeatureToShow('create')}>Create User</button>
<button onClick={() => setFeatureToShow('edit')}>Edit User</button>
{/* Depending on what is in the state show that component */}
{ featureToShow === 'list' ? <ListUser /> : null }
{ featureToShow === 'create' ? <CreateUser /> : null }
{ featureToShow === 'edit' ? <EditUser /> : null }
</>
)
In reality you'll probably want to enable clicking on the user's name in ListUser to show the EditUser component.
Related
How can I display the specific content that is assigned to a specific button in which if that specific button is clicked, it will display the assigned content of that specific button.
In my case, I have three buttons named "BBQ", "Bilao", and Chicken". These specific buttons contain their own specific content(which are also buttons but in a form of menu items containing their info).
Issue: My problem is that I cannot seem to display those specific content even if one of those specific buttons are clicked. For example, if "BBQ" will be clicked, it should display its specific menu item contents, the same process goes with "Bilao" and "Chicken".
I utilized a useState and an array of categories which contain the specific button names("BBQ", "Bilao", "Chicken) and also mapping the array. But all of these doesn't seem to work.
Problem now(pic):
Source code:
import * as React from "react";
import { useState } from "react";
import { Stack } from "#mui/material";
import ButtonCategoryStyle from "./ButtonCategoryStyle";
import BBQButtons from "./categoryButtons/BBQButtons";
import BilaoButtons from "./categoryButtons/BilaoButtons";
import ChickenButtons from "./categoryButtons/ChickenButtons";
export default function HomeOrderPage() {
const categories = ["BBQ", "Bilao", "Chicken"];
const [myCategory, setMyCategory] = useState("");
return (
<div>
<Stack spacing={0} direction="row">
{categories.map((category) => (
<ButtonCategoryStyle
title={category.toLocaleUpperCase()}
key={category}
onClick={() => setMyCategory(category)}
/>
))}
</Stack>
<div>
<p>
{myCategory === "police" && <BBQButtons />}
{myCategory === "chef" && <BilaoButtons />}
{myCategory === "doctor" && <ChickenButtons />}
</p>
</div>
</div>
);
}
Codesandbox link: https://codesandbox.io/s/vibrant-germain-76p1er?file=/src/HomeOrderPage.jsx:0-1025
How it should look like:
BBQ:
Bilao:
Chicken:
I based my code structure into this YT video, demo, and its Github source code:
https://www.youtube.com/watch?v=jRxoO-Zd0pQ (YT)
https://react-component-depot.netlify.app/react-basics/show-hide-elements (Demo)
https://github.com/codegeous/react-component-depot/blob/master/src/pages/ReactBasics/ShowAndHide/index.js (Github)
There are similar Stack questions that involves this process but still most of them did not work well for me.
Hoping for your guides and responses since I am exploring MUI and React at the moment and it will be a big help for me. Thank you very much!
There are two problems in your code.
{/*
HomeOrderPage.jsx
You have forgotten to change category names. Yours are "police, chef, doctor" right now.
*/}
{myCategory === "BBQ" && <BBQButtons />}
{myCategory === "Bilao" && <BilaoButtons />}
{myCategory === "Chicken" && <ChickenButtons />}
// styles removed just not to take space
// You need to use rest operator to pass all props
export default function ButtonCategoryStyle({ title, ...restProps }) {
return (
<Button
{...restProps}
>
{title}
</Button>
);
}
// Or you can just pass onClick method.
export default function ButtonCategoryStyle({ title, onClick }) {
return (
<Button
onClick={onClick}
>
{title}
</Button>
);
}
Hello, I don't know how to change component when clicking on the button on the left side, so it'll render the component into the right side, but only the one that I want, not all of it, I know how to clicking component, it'll transfer me into another route using Switch, etc but this doesn't seem like the case. Can someone help me out?
I can't figure out how to keep the button at the left side stay while the right side component is changing
Here are my code:
import { Component } from "react";
import UserManagement from "../UserManagement/index";
import RoleManagement from "../RoleManagement/index";
import QuizManagement from "../QuizManagement/index";
class Admin extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div class="admin-section">
<div class="admin-control col-25">
/- 3 buttons for 3 components I want to render
<button>
<label>User management</label>
</button>
<button>
<label>Role management</label>
</button>
<button>
<label>Quiz management</label>
</button>
</div>
<div class="admin-modify col-75">
/- When I click button the component will display here, I just don't know how to parse it into here but only one, if it like this it'll render all 3 of it.
<UserManagement />
<RoleManagement />
<QuizManagement />
</div>
</div>
);
}
}
export default Admin;
A simple solution would be:
Step 1 : Add a state called management in this.state = {}. Like
constructor(props) {
super(props);
// you can default this to any of the three
this.state = {management: "user"};
}
Step 2: Add onClick handler on the buttons like
<button onClick={() => {this.setState({management: "user"}) }}>
<label>User management</label>
</button>
<button onClick={() => {this.setState({management: "role"}) }}>
<label>Role management</label>
</button>
<button onClick={() => {this.setState({management: "quiz"}) }}>
<label>Quize management</label>
</button>
Step 3: Conditionally render your tables based on the state.
{this.state.managment === "user" && <UserManagement />}
{this.state.managment === "role" && <RoleManagement />}
{this.state.managment === "quiz" && <QuizManagement />}
Step 4: Turn up :).
Have you tried to simply hide/show the right component when listening to the user's "onClick" event on the left component?
So I have multiple components and a list of buttons. When I hit a button, I want to use reacthooks to display the corresponding component in {displayComponent}. I only want one component displaying at a time (so if you hit another button it will replace whatever was there previously).
Can someone tell me where i've gone wrong? This isn't working (it's just displaying all three components and the visibility doesn't change). My idea was to have the component display based on if displayComponent matched it's id.
How can I fix it and is there are more efficient way to accomplish this?
import Component1 from "./components/comp1";
import Component2 from "./components/comp2";
import Component3 from "./components/comp3";
function ComponentSelection() {
let [displayComponent, setDisplayComponent] = useState(null);
return(
<Button onClick={setDisplayComponent = "comp1">Click to display component 1</Button>
<Button onClick={setDisplayComponent = "comp2"}>Click to display component 2</Button>
<Button onClick={setDisplayComponent = "comp3"}>Click to display component 3</Button>
{displayComponent}
<Component1 id='comp1' display={displayComponent === 'comp1'} />
<Component2 id='comp2' display={displayComponent === 'comp2'} />
<Component3 id='comp3' display={displayComponent === 'comp3'} />
)
}
export default ComponentSelection
You misunderstood what hooks are. The second element in the returned array is a function to set it. Try this instead:
<Button onClick={() => setDisplayComponent("comp1")}>Click to display component 1</Button>
I have an app that displays data from an API and a button for loading more.
The problem I have is that the button flashes on the screen before the data list is fetched and displayed.
I want the button to display only at the bottom of the page after the list.
What is a way I can do this?
The code :
useEffect(() => {
setLoading(true);
fetchTopRatedMovies(pageNumber).then((newData) =>
setApiData({
...newData,
results: [...apiData.results, ...newData.results]
})
);
setLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pageNumber]);
return (
<div className='top-rated-page-wrapper'>
{isLoading ? (
<Loader />
) : (
<>
<MovieList results={results} />
<PageButton pageLimit={pageLimit} loadMore={loadMore} />
</>
)}
</div>
To clarify.
The button loads first and flashes before the data is rendered.
The button is then in the position where I want it at the bottom of the page.
I don't want to button to be visible until the data has been rendered.
You could use conditional render to render load more button when data > 0
{ apiData ? <PageButton pageLimit={pageLimit} loadMore={loadMore} /> : null }
I believe this article will answer your question. The author uses the same hook and speaks specifically how to manage the lifecycle event with a state variable.
https://daveceddia.com/useeffect-hook-examples/
I have an Alerts component which is responsible for rendering alerts from JSON supplied to it's props:
alert.js (cut down for brevity)
createAlert(alerts) {
return alerts.map(content => (
<Col key={content.ID} s={12}>
<div className="chip">
<Icon className="alert">error_outline</Icon>
<p>{content.Comment}</p>
<span onClick={() => this.props.onRead(content.ID)}>
<Icon className="closeAlert">close</Icon>
</span>
</div>
</Col>
));
}
render() {
let content = {};
if (!this.props.content) {
//Alerts are null so they are still loading.. show loader
content = this.createLoader();
} else if (!this.props.content.success){
//Error getting alerts
content = this.createAlertError(this.props.content.error);
}
else if (this.props.content.alerts.length === 0) {
//Alert array is null, therefor no alerts
content = this.createNoAlerts();
} else {
//Render Alerts
content = this.createAlert(this.props.content.alerts);
}
return <div>{content}</div>;
}
}
In the above snippit, you can see that if
this.props.alerts
is an array with elements, then it will run
createAlert()
which will create an array of React Components (in this case its just React-Materialize component which is just a <div></div>)
the part I am interested in is the span with the onClick event
<span onClick={() => this.props.onRead(content.ID)}>
<Icon className="closeAlert">close</Icon>
</span>
This run an event from the parent component.
The method that is run in the parent is as follows:
alertRead(id) {
this.props.deleteAlert(id);
}
What I would like, is some way to add a spinning loader icon into the button on the click, in jQuery it would be:
$(button).on("click", function(){
this.html("<i class='fa fa-spin fa-spinner'></i>"); //Spinner Icon
});
The question is, how do I edit the HTML of the button that is clicked on click?
No Redux version
I don't see any redux relation in the code so I will assume that you are not using it or not using it in this particular flow.
What you need to do is to add state to the Alert component and do two things in onClick handler:
() => { this.props.onRead(content.ID); this.setState({clicked: true});}
Of course you need to have state initialization with clicked: false. Second thing is to use this state in rendering:
{this.state.clicked && <Loader />}
{!this.state.clicked && <YourButton />}
So when clicked show loader when not clicked show button. Above code examples are only for showing you the right path.
Version assuming of Redux using.
If you are using redux then alert needs to have connection with the store like:
connect((state) => ({ isClicked: getIsButtonClicked(state)}), { dispatchClick })(AlertComponent)
And you need to dispatch click action after click ( it will set the store state responsible for that - clicked on true.
() => { this.props.onRead(content.ID); this.props.dispatchClick();}
Also finnaly you need to use this prop in rendering:
{this.props.isClicked && <Loader />}
{!this.props.isClicked && <YourButton />}
This solution will cover all instances of Alert component. I am not covering here the redux part.