I'm not a developer and I'm currently blocked. I'm trying to create a "go home" button or hide this restart button and show it to the user only when he reaches the last view. I can't find a solution...
Thanks in advance for your help.
import React, { useState } from 'react';
import './App.css';
import { SelectSign } from './components/SelectSign';
import { SelectTimeframe } from './components/SelectTimeframe';
import { Horoscope } from './components/Horoscope';
function App() {
const [selectedSign, setSelectedSign] = useState(null);
const [
selectedTimeframe,
setSelectedTimeframe,
] = useState('today');
const restart = () => {
setSelectedSign(null);
setSelectedTimeframe('today');
};
return (
<div className="App">
<h1>The Horoscope App</h1>
{!selectedSign && (
<SelectSign onSignSelected={setSelectedSign} />
)}
{selectedSign && !selectedTimeframe && (
<SelectTimeframe
onTimeframeSelected={setSelectedTimeframe}
/>
)}
{selectedSign && selectedTimeframe && (
<Horoscope
sign={selectedSign}
timeframe={selectedTimeframe}
/>
)}
<button onClick={restart}>Restart</button>
</div>
);
}
export default App;
When selectSign button is clicked you are setting the value in the selectedSign.
You can check if else condition here using ternary operator in the JSX template.
If selectedSign value is present then show GO home button else it will show Restart button.
function App() {
const [selectedSign, setSelectedSign] = useState(null);
const [
selectedTimeframe,
setSelectedTimeframe,
] = useState('today');
const restart = () => {
setSelectedSign(null);
setSelectedTimeframe('today');
};
return (
<div className="App">
<h1>The Horoscope App</h1>
{!selectedSign && (
<SelectSign onSignSelected={setSelectedSign} />
)}
{selectedSign && !selectedTimeframe && (
<SelectTimeframe
onTimeframeSelected={setSelectedTimeframe}
/>
)}
{selectedSign && selectedTimeframe && (
<Horoscope
sign={selectedSign}
timeframe={selectedTimeframe}
/>
)}
{
selectedSign?<button>Go Home</button>:<button onClick={restart}>Restart</button>
}
</div>
);
}
export default App;
Related
I have two bottom sheets clicking the on-click button pops up the bottom sheet. clicking on the second bottom sheet button does the same, my problem is that nothing is being displayed on the second screen when it pops up. Below is my code. I would so much appreciate it if anyone can help out. I have been stuck in this for weeks
my home.js has all the use state that toggles all buttons including swipeable bottom sheets
import React, {useState} from 'react';
import Header from "../components/Header";
import DailyCard from "../components/DailyCard";
import styled from "styled-components";
import RoomInfoCard from "../components/RoomInfoCard";
import {AiOutlinePlus} from "react-icons/ai";
import { BsGrid3X2Gap } from 'react-icons/bs';
import BottomSheet from '../components/BottomSheet';
import RoomCard from "../Data/RoomCard.json"
import newRoomData from "../Data/newRoomData.json"
const Home = () => {
const [itemsVisible, setItemsVisible] = useState(true);
const [sheetVisible, setSheetVisible] = useState(false)
const [sheetCreateRoom, setSheetCreateRoom] = useState(false)
const [cardId, setCardId] = useState(1);
return (
<>
<>
<Header/>
<Container>
<DailyCard/>
</Container>
<RoomInfoCard/>
<ActionBtn>
<button onClick={()=> setSheetVisible(true)} >
<AiOutlinePlus style = {{marginRight : "4px"}} />
Start a room
</button>
<button>
<BsGrid3X2Gap style ={{marginRight: "4px"}}/>
</button>
</ActionBtn>
<BottomSheet
sheetTitle = "start room"
setSheetVisible={(item)=> setSheetVisible(item)}
sheetVisible={sheetVisible}
cardDetail= {RoomCard.find((item)=> item.id === cardId)}
setItemsVisisheet titleem)=> setItemsVisible(item)}
setSheetCreateRoom = {(item)=>{
sheet visibleLoaderVisibility(true);
setTimeout(()=>{
setSheetCreateRoom(item)
setLoaderVisibility(false)
}, 1000);
}}
/>
<BottomSheet
sheetTitle = "new room"
setSheetVisible = {(item)=> setSheetCreateRoom(item)}
sheetVisible = {sheetCreateRoom}
cardDetail = {newRoomData}
setItemsVisible = {(item)=> setItemsVisible(item)}
/>
</>
</>
)
}
React.js```
import React from 'react';
import SwipeableBottomSheet from "react-swipeable-bottom-sheet";
import styled from "styled-components";
import StartRoom from './bottomSheets/StartRoom'
import NewRoom from "./bottomSheets/NewRoom";
const BottomSheet = (props)=> {
return (
< >
<SwipeableBottomSheet
overlay={true}
open = { props.sheetVisible }
onChange = {
() => {
props.setSheetVisible(!props.sheetVisible)
props.setItemsVisible(true) }
}
fullScreen = { props.sheetTitle === 'room detail' ? true : false }>
<div style = {
{ backgroundColor: props.sheetTitle === "profile" ? "transparent" : " " ,
height:"250px",
overflowY:"hidden",
} } >
{ props.sheetTitle === "new room " ? (
<NewRoom
setSheetCreateRoom = {props.setSheetCreateRoom}
cardDetail = {props.cardDetail}
setSheetVisible = { (item)=> {
props.setSheetVisible(item)
props.setItemsVisible(true)
}}
/>
) : props.sheetTitle === "start room" ? (
<StartRoom
setSheetCreateRoom = { props.setSheetCreateRoom }
setSheetVisible = { (item)=>{
props.setSheetVisible(item);
props.setItemsVisible(true);
}
}
/>
) :(
" "
)
}
</div>
</SwipeableBottomSheet>
</>
)
}
export default BottomSheet;
```
and when the user clicks "Selected," show the Select,Please take a look at my code and tell me where I'm going wrong.
This is the App.js file I'm working on.
import "./styles.css";
import MainShow from "./Show";
import { useState } from "react";
export default function App() {
var [isDone, setDone] = useState(false);
const Delected = () => {
setDone(!isDone);
console.log("set");
};
const Selected = () => {
setDone(!isDone);
console.log("Del");
};
return (
<div className="App">
<h1>Hello ,Problem Solver</h1>
<MainShow DoneMain={isDone} /> //imported
<button onClick={Delected}>Delected</button> //Delected button
<button onClick={Selected}>Selected</button> //Selected button
</div>
);
}
This MainShow file has the Main function.Look at my code on CodeSandbox
import React, { useState } from "react";
const Main = (props) => {
const [isDone] = useState(props.DoneMain);
console.log(isDone);
return (
<div>
<div>
<div
className="container"
style={{ display: isDone ? "block" : "none" }}
>
<p> Select</p>
</div>
<p>Hello</p>
</div>
</div>
);
};
export default Main;
When the user clicks on the "Deleted" button, I want "Select" to be hidden, and when the user clicks on "Selected," I want "Select" to be displayed.
Check for state value changes and show/hide
const Delected = () => {
setDone(false);
console.log("set");
};
const Selected = () => {
setDone(true);
console.log("Del");
};
{isDone && <MainShow DoneMain={isDone} />}
Demo
I am testing this component Sidebar
const Sidebar = () => {
const { modalVisible, modalVisibleHandler } = useModalVisible();
return (
<div className="sidebar">
<Profile />
<Menu />
<WorkSpace all={true} />
<SidebarButton openModal={modalVisibleHandler} />
{modalVisible && (
<Portal>
<TaskCreate />
</Portal>
)}
</div>
);
};
My Portal component
import { useEffect } from "react";
import ReactDOM from "react-dom";
const modalRoot = document.getElementById("modal-root");
export default function Portal({ children }: { children: any }) {
const el = document.createElement("div");
useEffect(() => {
if (modalRoot) {
modalRoot.appendChild(el);
}
return () => {
if (modalRoot) modalRoot.removeChild(el);
};
}, [el]);
return ReactDOM.createPortal(children, el);
}
and TaskCreate component
const TaskCreate = () => (
<div
className="task-create task-view"
id="task-create"
>
this component will open when user click button in Sidebar component
</div>
);
I have in TaskCreate component id="task-create" so before user click on "open modal" in Sidebar, TaskCreate component with id "task-create" I need to test that this id not.toBeInTheDocument() and after user click toBeInTheDocument()
The problem is that Portal is connect with id "modal-root" which is in the index.html and my test can't get this bind
I made My code.
When Click the button A, appear AAA.
Or Click the button B, appear BBB, Click the button C, appear CCC.
// Main > RightMain.js
import React, { useState } from 'react'
function RightMain() {
const [screen, setScreen] = useState('');
const A = () => {
setScreen('A')
}
const B = () => {
setScreen('B')
}
const C = () => {
setScreen('C')
}
return (
<div>
<button onClick={A}>A</button>
<button onClick={B}>B</button>
<button onClick={C}>C</button>
{screen === 'A' && <div>AAA</div>}
{screen === 'B' && <div>BBB</div>}
{screen === 'C' && <div>CCC</div>}
</div>
)
}
export default RightMain
And I wanna separate My Code(RightMain.js).
When I Click the Button on the RightMain.js.
The Result appear's on the Formations.js like the image below.
But I don kno how to bring value(RightMain.js's screen) to the Formations.js.
// Main > LeftMain.js
import React from 'react'
import RadioBtn from './LeftMain/RadioBtn';
import Formation from './LeftMain/Formation';
function LeftMain() {
return (
<div>
<div>
<RadioBtn />
</div>
<div>
<Formation />
</div>
</div>
)
}
export default LeftMain
//Main > LeftMain > Formation.js
import React, { useState } from 'react'
import RightMain from '../RightMain';
function Formation() {
return (
<div>
</div>
)
}
export default Formation
Thx
If I understand correctly, LeftMain and RightMain are sibilings, and Formation is a child of LeftMain.
One possible approach is to use Context API.
Something like this should work:
// Define the default value
// or return null and take that into consideration when using "useContext"
export const MyCurrentScreenContext = React.createContext({
setScreen: () => void 0,
screen: ''
});
export const MyCurrentScreenProvider = props => {
const [screen, setScreen] = useState('');
const value = useMemo(() => ({ screen, setScreen }), [screen, setScreen]);
return (
<MyCurrentScreenContext.Provider value={value}>
{props.children}
</MyCurrentScreenContext.Provider>
);
}
const Main = () => {
...
return (
<MyCurrentScreenProvider>
<LeftMain />
<RightMain />
...
</MyCurrentScreenProvider>
);
}
const RightMain() {
const { setScreen } = useContext(MyCurrentScreenContext);
....
};
const Formation() {
const { screen } = useContext(MyCurrentScreenContext);
....
};
Read more about context api at the official docs
From what I understand, you want to pass the values down to the child components. If that is correct then you could pass them as parameters when calling it and using props to receive them inside the child component. Something like this.
<div>
<RadioBtn randomVal="value" />
</div>
I am fairly new to Context API. So bassicaly, I want when I press on the Button in the ButtonComponent everything in ButtonComponent disapears as well in ImageComponent but when I click on the Button nothing happens. I am kind of stuck with this I would be very grateful if I got someone to help me if possible. Thanks in Advance!
//HiddenContext
import React from "react";
export const HiddenContext = React.createContext(false);
function HiddenProvider({ children }) {
const [hideButton, setHideButton] = React.useState(false);
function handleClick() {
setHideButton(true);
}
return (
<HiddenContext.Provider value={{ hideButton, handleClick }}>
{children}
</HiddenContext.Provider>
);
}
// App Component/Parent
import React, { useState } from 'react';
import './App.css';
export const HiddenContext = React.createContext(false);
function HiddenProvider({ children }) {
const [hideButton, setHideButton] = React.useState(false);
function handleClick() {
setHideButton(true);
}
return (
<HiddenContext.Provider value={{ hideButton, handleClick }}>
{children}
</HiddenContext.Provider>
);
}
function App() {
const { hideButton } = React.useContext(HiddenContext);
return (
<HiddenProvider>
<div className="App">
<ImageComponent hideButton={hideButton} />
</div>
</HiddenProvider>
);
}
//ButtonComponent
import React, {useState,ReactFragment} from 'react'
import { HiddenContext, } from './HiddenContext';
function ButtonComponent() {
const { hideButton, handleClick } = React.useContext(HiddenContext);
return (
<React.Fragment>
{!hideButton && (
<li>
<img className="image" src="./icons" alt="" />
<Button
onClick={handleClick}
variant="outlined"
className="button__rightpage"
>
Hide
</Button>
<caption className="text"> Hide</caption>
</li>
)}
</React.Fragment>
);
}
// ImageComponent
import React, {useState, ReactFragment} from 'react'
import { HiddenContext, } from './HiddenContext';
const ImageComponent = () => {
const { hideButton } = React.useContext(HiddenContext);
return (
<div>
{!hideButton && (
<React.Fragment>
<img src="icons/icon.png" alt="" />
<caption>Image </caption>
</React.Fragment>
)}
</div>
);
};
We created here 2 context - instead of 1
I make a codesendbox for us to see the fix.
https://codesandbox.io/s/focused-night-i95fr
We should create context only one time, to wrap the App component with the provider, and we can use this context like you did wherever we want
And relative to the beginner, it seems from your code that you understand what you are doing
about your comment - attached a pic
You are trying to access the context value outside the provider (in App).
Try to remove this from App, like so:
function App() {
return (
<HiddenProvider>
<div className="App">
<ImageComponent />
</div>
</HiddenProvider>
);
}