As of right now my searchbar wont minimize, I don't really know how to write a code so if it's empty it doesn't display anything. Also I would like to be able to click somewhere else on the screen to make it dissapear. Anyone got any ideas? :)
GIF of problem: https://gyazo.com/518e8a14216b527c003aab7fc32f343c
My input:
<input
className="form-control"
placeholder="Search CARLDb..."
value={props.value}
onChange={(event) => props.setSearchValue(event.target.value)}>
</input>
My search list: https://gyazo.com/a7c5b2f2ada0379f2d5b0cee717d7d07
import React from "react";
import { Link } from "react-router-dom";
import "./components.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faStar } from "#fortawesome/free-solid-svg-icons";
import placeholder from './Images/placeholder.jpg'
const image_url = "https://image.tmdb.org/t/p/w500";
const SearchList = (props) => {
return (
<>
{props.tvShow?.map((movie) => (
<div key={movie.id} className="search-box">
<img
className="search-image"
src={movie.poster_path === null ? placeholder : image_url + movie.poster_path}
alt={movie.poster_path}
/>
<span className="search-span">
<FontAwesomeIcon id="search-star" icon={faStar} />
{movie.vote_average}
</span>
<a className="search-link" href={`https://www.themoviedb.org/movie/${movie.id}`} target="_blank" rel="nooponer noreferrer">
<p className="searchp" onClick={()=> props.handleFavouritesClick(movie)}>{movie.title || movie.name}</p>
</a>
</div>
))}
</>
);
};
export default SearchList;
CSS:
.search-list { /*built with container fluid*/
position: absolute;
left: 38%;
width: 350px;
display: inline;
z-index: 99;
max-height: 40%;
max-width: 550px;
}
.search-box {
background-color: #1a1a1a;
height: 75px;
max-width: 505px;
display: flex;
border: 1px solid black;
overflow: hidden;
}
Please let me know if I should there is any other code you would like to see. I'm a beginner to React and JavaScript.
Thanks! :)
edit: refered to searchbar instead of my results. I would like to keep the searchbar at all times but I want my resultbox to dissapear.
edit2: added navbar.js and app.js
Navbar.js
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import logo from "../carldb2.png";
import "bootstrap/dist/css/bootstrap.min.css";
import "./components.css";
import SearchBox from "./SearchBox";
import SearchList from "./SearchList";
const Navbar = (props) => {
const getSearchRequest = async () => {
const search_url = `https://api.themoviedb.org/3/search/movie?api_key=1e08baad3bc3eca3efdd54a0c80111b9&language=en-US&query=${props.searchValue}&page=1&include_adult=false`;
const response = await fetch(search_url);
const responseJson = await response.json();
if (responseJson.results) {
props.setMovieSearch(responseJson.results.slice(0, 7));
}
};
useEffect(() => {
if (props.searchValue) {
getSearchRequest();
}
}, [props.searchValue]);
return (
<div>
<nav className="navbar">
<div className="nav-center d-flex">
<Link to="/">
<img className="logo" src={logo} alt="logo" />
</Link>
<SearchBox
searchValue={props.searchValue}
setSearchValue={props.setSearchValue}
/>
</div>
</nav>
<div className="container-fluid search-list">
<SearchList
tvShow={props.movieSearch}
handleFavouritesClick={props.addRecentlyViewed}
/>
<Link to="/search">
<button className="results" onClick={closeFunction()}>
<h7 className="results-text">See all results for "{props.searchValue}"</h7>
</button>
</Link>
</div>
</div>
);
};
export default Navbar;
app.js
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Homepage from "./components/Homepage";
import Footer from "./components/Footer";
import Navbar from "./components/Navbar";
import React, { useEffect } from "react";
import SearchPage from "./components/SearchPage";
function App() {
const [searchValue, setSearchValue] = React.useState("");
const [movieSearch, setMovieSearch] = React.useState([]);
const [tvShow, setTVShow] = React.useState([]);
const [recentlyViewed, setRecentlyViewed] = React.useState([]);
useEffect(() => {
const recentlyMovies = [
...new Set(
JSON.parse(localStorage.getItem("recently-watched"))
),
];
if (recentlyMovies) {
setRecentlyViewed([...new Set(recentlyMovies.slice(0, 5))]);
}
}, []);
const saveToLocalStorage = (items) => {
localStorage.setItem("recently-watched", JSON.stringify(items));
};
const addRecentlyViewed = (movie) => {
recentlyViewed.forEach((item) => {
let index = recentlyViewed.indexOf(item);
if (item.id === movie.id) {
recentlyViewed.splice(index, 1);
}
});
const newRecentlyViewed = [movie, ...recentlyViewed];
setRecentlyViewed([...new Set(newRecentlyViewed)].slice(0, 5));
saveToLocalStorage(newRecentlyViewed);
};
return (
<Router>
<Navbar
searchValue={searchValue}
setSearchValue={setSearchValue}
addRecentlyViewed={addRecentlyViewed}
movieSearch={movieSearch}
setMovieSearch={setMovieSearch}
/>
<Routes>
<Route
path="/"
element={
<Homepage
tvShow={tvShow}
setTVShow={setTVShow}
addRecentlyViewed={addRecentlyViewed}
recentlyViewed={recentlyViewed}
setRecentlyViewed={setRecentlyViewed}
/>
}
/>
<Route
path="/search"
element={
<SearchPage
handleFavouritesClick={addRecentlyViewed}
tvShow={movieSearch}
setTVShow={setTVShow}
searchValue={searchValue}
setSearchValue={setSearchValue}
addRecentlyViewed={addRecentlyViewed}
/>
}
/>
</Routes>
<Footer />
</Router>
);
}
export default App;
In the Navbar component you could add some flag to show / hide the SearchList
const showList = props.searchValue !== "";
{
showList ? (
<div className="container-fluid search-list">
<SearchList
tvShow={props.movieSearch}
handleFavouritesClick={props.addRecentlyViewed}
/>
<Link to="/search">
<button className="results" onClick={closeFunction()}>
<h7 className="results-text">
See all results for "{props.searchValue}"
</h7>
</button>
</Link>
</div>
) : null;
}
Related
I'm making shopping page with React.
I want to go detail page when i click a goods image.
I was trying to get goods's id that clicked to me by <Link className='product-link' to={/goods/${id}}> this code in GoodsList code.
and then, In GoodsDetail code, i was trying to get goods's id that cliked to me and to render the goods's data
But it seems that the in the GoodsList code doesn't work well.
when i click the goods image, page doesn't go to goods/{id}, but go to goods/undefined.
How can i fix my code?
This is App.js code
import React from 'react';
import './App.css';
import Navbar from './components/Navbar';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages';
import Sell from './pages/sell';
import Search from './pages/search';
import AboutMe from './pages/aboutme';
import Login from './pages/login';
import TradeRecord from './pages/traderecord';
import SignUp from './pages/signup';
import Zzim from './pages/zzim';
import Selling from './pages/selling';
import Goods from './pages/goods';
const App = () => {
return (
<div className='App'>
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/sell" element={<Sell />}></Route>
<Route path="/search" element={<Search />}></Route>
<Route path="/signup" element={<SignUp />}></Route>
<Route path="/login" element={<Login />}></Route>
<Route path="/aboutme" element={<AboutMe />}></Route>
<Route path="/selling" element={<Selling />}></Route>
<Route path="/zzim" element={<Zzim />}></Route>
<Route path="/traderecord" element={<TradeRecord />}></Route>
<Route path="/goods/:id" element={<Goods />}></Route>
</Routes>
</BrowserRouter>
</div>
)
}
export default App;
This is Goods List page code
import React, {useState, useEffect} from 'react';
import { Link, useParams } from 'react-router-dom';
import axios from 'axios';
import './index.css';
const SearchView = (props) => {
const [boards, setBoards] = useState([]);
const {id} = useParams();
useEffect(() => {
(async function () {
const response = await axios.get("https://27.96.131.85:8443/api/boards")
.catch((err) => {
console.log(err);
});
const boards = response.data;
setBoards(boards);
console.log(response.data);
})();
}, []);
return(
<div>
<hr />
<div id='product-list'>
{
boards.map(function(boards, index){
return (
<div className='product-card'>
<Link className='product-link' to={`/goods/${id}`}>
<div>
{
boards.boardImages[0]
? <img className="product-img" width="100" height="100"
src={`https://27.96.131.85:8443/api/images/${boards?.boardImages[0]?.id}`} />
: <img className="product-img" width="100" height="100" src={require("../../images/noImage.png")} />
}
</div>
<div className='product-contents'>
<span className='product-name'>
{boards.goodsName}
</span>
<span className='product-price'>
{boards.price}원
</span>
<div className='product-seller'>
<span>{boards.writer}</span>
</div>
</div>
</Link>
</div>
)
})
}
</div>
</div>
);
};
export default SearchView;
This is Goods detail code
import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
const Goods = (props) => {
const [boards, setBoards] = useState({});
const [images, setImages] = useState([]);
const {id} = useParams();
useEffect(() => {
(async function () {
const response = await axios.get(`https://27.96.131.85:8443/api/boards/${id}`, {
withCredentials: true,
});
const boards = response.data;
const images = boards.boardImages;
console.log(response.data);
setBoards(boards);
setImages(images);
})();
}, []);
return(
<div id="product">
상품명: <span className="product-name">{boards.goodsName}</span>
<br />
가격: <span className="product-price">{boards.price}원</span>
<div className="product-seller">
작성자: <span>{boards.writer}</span>
</div>
<div className="product-isSale">
판매여부: <span>{boards.sale?.toString()}</span>
</div>
<div className="product-isLiked">
찜 여부: <span>{boards.liked?.toString()}</span>
</div>
<div className="product-atCreated">
작성 시간: <span>{boards.createdDateTime}</span>
</div>
<div className="product-atModified">
수정 시간: <span>{boards.modifiedDateTime}</span>
</div>
<div className="product-images">
{
images.map((image) => {
return (
<img className="product-img" width="100" height="100"
src={`https://27.96.131.85:8443/api/images/${id}`} />
)
})
}
</div>
</div>
);
};
export default Goods;
There is a mistake in your goods list page code,
solution:
{boards.map(function (boards, index) {
return (
<div className="product-card">
<Link className="product-link" to={`/goods/${boards.id}`}>
<div>
{boards.boardImages[0] ? (
<img
className="product-img"
width="100"
height="100"
src={`https://27.96.131.85:8443/api/images/${boards?.boardImages[0]?.id}`}
/>
) : (
<img
className="product-img"
width="100"
height="100"
src={require("../../images/noImage.png")}
/>
)}
</div>
<div className="product-contents">
<span className="product-name">{boards.goodsName}</span>
<span className="product-price">{boards.price}원</span>
<div className="product-seller">
<span>{boards.writer}</span>
</div>
</div>
</Link>
</div>
);
})}
as you used the map function to iterate over the boards array,
and you've assigned variable name 'boards' to each element of the array
so the variable boards itself is an object that contains the id property.
so you have to write boards.id to fix your issue
I hope this might help you
I think it should be boards.id, instead of id..
<Link className='product-link' to={`/goods/${id}`}>
Can you please share your data structure?
This is my app.js
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import "./App.css";
import Home from "./Home";
import Navbar from "./Navbar";
import Works from "./Works";
function App() {
return (
<>
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/works" element={<Works />} />
</Routes>
</Router>
</>
);
}
export default App;
This is my Home.js
import React, { useEffect, useState } from "react";
import "./App.css";
import ClimbingBoxLoader from "react-spinners/ClimbingBoxLoader";
import "./mainpage.css";
import cloud1 from "./images/cloud1.svg";
import cloud02 from "./images/cloud02.svg";
import cloud2 from "./images/cloud2.svg";
import moon from "./images/moon.svg";
import cloud3 from "./images/cloud3.svg";
import cloud01 from "./images/cloud01.svg";
import { useNavigate } from "react-router-dom";
import {
MouseParallaxChild,
MouseParallaxContainer,
} from "react-parallax-mouse";
import Navbar from "./Navbar";
function Home() {
let navigate = useNavigate();
const [loading, setloading] = useState(false);
useEffect(() => {
setloading(true);
setTimeout(() => {
setloading(false);
}, 1000);
}, []);
return (
<MouseParallaxContainer className="App">
{loading ? (
<ClimbingBoxLoader size={20} color={"#F37A24"} loading={loading} />
) : (
<MouseParallaxContainer
className="main-page"
containerStyles={{
width: "100%",
overflow: "none",
}}
>
<Navbar />
<h1 className="heading">SASWATA</h1>
<h1 className="heading2">GHOSH</h1>
<span className="bar1"></span>
<span className="bar2"></span>
<p className="para">web developer</p>
<p className="scrolldown">SCROLL DOWN</p>
<span className="verticaline"></span>
<MouseParallaxContainer
className="moon"
containerStyles={{
width: "100%",
overflow: "none",
}}
>
<MouseParallaxChild
className="moon_text"
factorX={0.01}
factorY={0.01}
>
<p>PORTFOLIO</p>
</MouseParallaxChild>
<MouseParallaxChild
className="moon_img"
factorX={0.03}
factorY={0.05}
>
<img src={moon} alt="" />
</MouseParallaxChild>
<MouseParallaxChild
className="cloud01"
factorX={0.04}
factorY={0.06}
>
<img src={cloud01} alt="" />
</MouseParallaxChild>
<MouseParallaxChild
className="cloud02"
factorX={0.03}
factorY={0.05}
>
<img src={cloud02} alt="" />
</MouseParallaxChild>
<MouseParallaxChild
className="cloud_front1"
factorX={0.04}
factorY={0.07}
>
<img src={cloud1} alt="cloud1" />
</MouseParallaxChild>
<MouseParallaxChild
className="cloud3"
factorX={0.03}
factorY={0.05}
>
<img src={cloud3} alt="" />
</MouseParallaxChild>
<MouseParallaxChild
className="cloud2"
factorX={0.06}
factorY={0.05}
>
<img src={cloud2} alt="cloud2" />
</MouseParallaxChild>
</MouseParallaxContainer>
<div className="nav-left">
<span className="span1"></span>
<span className="span2"></span>
<span className="span3"></span>
<span className="span4"></span>
</div>
</MouseParallaxContainer>
)}
</MouseParallaxContainer>
);
}
export default Home;
This is my Works.js
import React, { useEffect, useState } from "react";
import "./App.css";
import ClimbingBoxLoader from "react-spinners/ClimbingBoxLoader";
import "./Works.css";
import cloud02 from "./images/cloud02.svg";
import works from "./images/LandingPage.png";
import { useNavigate } from "react-router-dom";
import cloud01 from "./images/cloud01.svg";
import {
MouseParallaxChild,
MouseParallaxContainer,
} from "react-parallax-mouse";
import Navbar from "./Navbar";
function Home() {
let navigate = useNavigate();
const [loading, setloading] = useState(false);
useEffect(() => {
setloading(true);
setTimeout(() => {
setloading(false);
}, 1000);
}, []);
return (
<MouseParallaxContainer className="App">
<MouseParallaxContainer
className="main-page"
containerStyles={{
width: "100%",
overflow: "none",
}}
>
<Navbar />
<h1 className="heading">
Web Sec<span className="name-span">urity</span>
</h1>
<h1 className="heading2">Project</h1>
<span className="bar1"></span>
<span className="bar2"></span>
<p className="para">website</p>
<MouseParallaxContainer
className="moon"
containerStyles={{
width: "100%",
overflow: "none",
}}
>
<MouseParallaxChild className="cloud01" factorX={0.04} factorY={0.06}>
<img src={cloud01} alt="" />
</MouseParallaxChild>
<img className="works-img" src={works} alt="" />
</MouseParallaxContainer>
<div className="nav-left">
<span className="span11"></span>
<span className="span12"></span>
<span className="span13"></span>
<span className="span14"></span>
</div>
<div className="page-number">
<p>01</p>
</div>
</MouseParallaxContainer>
</MouseParallaxContainer>
);
}
export default Home;
I want to perform mouse slide such that it lands on new page on mouse scroll.
This is the website I am referring.(https://kuon.space/).
It is done using HTML and jquery but I am trying it with React.js and CSS. I hope you can help me. I have tried almost all libraries and couldn't help myself.
write a component that wrapped by <Switch> tag from react-router-dom, inside, add routes, and for every routes you can decide what you display. it should look something like this:
<Switch>
<Route path="/image-1">
<img src={...}/>
</Route>
<Route path="/image-2">
<img src={...}/>
</Route>
<Route path="/image-3">
<img src={...}/>
</Route>
.
.
.
</Switch>
now, for slider button, use the Link from react-router-dom, you can do something like this:
<Link to={`image-${id > 0 ? id - 1 : 0}`}>Previous</Link>
<Link to={`image-${id < length-of-items ? id + 1 : length-of-items}`}>Next</Link>
now all you need to do is to have a state which holds the current image id (which will be the index of the image in the list) and you are good to go.
I am trying to fetch coingecko-api to access live price of bitcoin. I am trying to pass return props of getServerSideProps to my <CalculatorBuy /> component which is the part of <Main /> component. I was trying to import async function in calculatorbuy.js but i'm getting undefined object. How to pass props from index.js to main.js and calculatorbuy.js components. In index.js everything work like a charm but i would like to use props value directly in components.
index.js
export default function Home(props) {
const {data} = props.result;
console.log(data);
return (
<div className="container">
<Head>
<title>Buy BTC</title>
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
</Head>
<Header />
<Main />
<Footer />
<style jsx> {`
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
`} </style>
</div>
)
}
export async function getServerSideProps(context) {
const result = await coinGeckoClient.simple.price({
ids: "bitcoin",
vs_currencies: "eur",
});
return {
props: {
result,
},
}
}
main.js
import React, { useState } from 'react';
import Button from '#material-ui/core/Button';
import Calculatorbuy from './calculatorbuy.js'
import Calculatorsell from './calculatorsell.js'
export default function Main() {
const [ showMe, setShowMe ] = useState(true);
function toggle (){
if (!showMe) {
setShowMe(true);
}
else {
setShowMe(true);
}
}
function toggle2 (){
if (showMe) {
setShowMe(false);
}
else {
setShowMe(false);
}
}
return (
<main className="main">
<div className="box">
<div className="buttons">
<Button onClick={toggle} variant="outlined" color="primary" style={{width: 120, marginRight: 10}}>
KUP
</Button>
<Button onClick={toggle2} variant="outlined" color="secondary" style={{width: 120, marginRight: 10}}>
SPRZEDAJ
</Button>
<Button variant="outlined" color="default" style={{width: 120,}}>
HISTORIA
</Button>
</div>
<div style={{ display: showMe?"block":"none" }}>
<Calculatorbuy />
</div>
<div style={{ display: !showMe?"block":"none" }}>
<Calculatorsell />
</div>
</div>
<div className="room-for-socials"></div>
import React, { useState } from 'react';
import TextField from '#material-ui/core/TextField';
import Button from '#material-ui/core/Button';
import Livebsv from './livebsv.js';
export default function Calculatorbuy() {
const [value, setValue] = useState(0);
return (
<form className="calculator" noValidate autoComplete="off">
<div>
<Livebsv />
</div>
<div className="typebox">
<div className="textfield">
<TextField error={false} id="outlined-number" label="PLN" helperText="Min. wartość 100zł"
type="tel"
value={value}
InputProps={{
inputProps: { min: "100", max: "5000", step: "0.01" }
}}
variant="outlined"
onKeyPress={(e) => {
if (!/[0-9]/.test(e.key)) {
e.preventDefault();
}
}}
onChange={(e) => setValue(e.currentTarget.value)}
onKeyPress={(e) => {
if (!/[0-9]/.test(e.key)) {
e.preventDefault();
}
}}
onBlur={(e) => {
if (e.currentTarget.value > 0 & e.currentTarget.value < 100 )
setValue(100);
else if (e.currentTarget.value > 5000)
setValue(5000);
}}
/>
</div>
<div className="textfield">
<TextField disabled id="outlined-disabled" value={(value).toFixed(8)} label="BSV" variant="outlined"
You started well by loading the result on index.js(getServerSideProps).
Then, to pass the data to Main, you have to add it as a property for the component:
<Main data={data} />
Now, as Main expects a parameter, it has to be defined in main.js:
export default function Main(props) {
const data = props.data;
...
}
Then, for the Calculatorbuy component you have to do the same like on Main. Define the props and use it.
I trying to find a way to open the navbar of ReactJS app when i'm clicking on my "MENU" button.
At the beginning my nav component have a width of 0px (with overflow : hidden). When i'm clicking on the button my nav should have a width of 400px. I'm a beginner with React.
I have two React Components :
Topbar
export default function Topbar() {
return (
<div className="topbar__container">
<div className='topbar__menuButton'>
<Link className="topbar__link">MENU</Link>
</div>
<div className="topbar__title">
<Link to="/" className="topbar__link">EDGAR</Link>
</div>
</div>
)
}
Nav
const Nav = () => {
return (
<div className="navbar__container">
<Query query={CATEGORIES_QUERY} id={null}>
{({ data: { categories } }) => {
return (
<nav className="nav">
<ul>
{categories.map((category, i) => {
return (
<li key={category.id}>
<Link to={`/category/${category.id}`} className="nav__link">
{category.name}
</Link>
</li>
)
})}
</ul>
</nav>
)
}}
</Query>
</div>
)
}
export default Nav
To achieve something like that you have to set this logic in the common parent of both component (here App for the example).
App will manage a state to determine if the Nav is open or not. The state is called isMenuOpen and can be changed using the setIsMenuOpen() function. We will give to the children Nav the state isMenuOpen and to the children TopBar a callback from the function setIsMenuOpen():
App.jsx
import React from "react";
import TopBar from "./TopBar";
import Nav from "./Nav";
export default function App() {
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
return (
<div className="App">
<TopBar setMenuStatus={setIsMenuOpen} />
<Nav isOpen={isMenuOpen} />
</div>
);
}
Then the TopBar have to set the value of isMenuOpen to true using the function setIsMenuOpen() from the props.
TopBar.jsx
import React from "react";
export default function Topbar({ setMenuStatus }) {
return (
<div className="topbar__container">
<div className="topbar__menuButton">
<button
type="button"
onClick={() => {
setMenuStatus(true);
}}
>
Menu
</button>
</div>
</div>
);
}
Then the component Nav will set a specific class (here .open) if isOpen coming from props is true.
Nav.jsx
import React from "react";
import "./styles.css";
export default function Nav({ isOpen }) {
return (
<div id="nav" className={isOpen ? "open" : ""}>
Menu
</div>
);
}
styles.css
#nav {
display: none;
}
#nav.open {
height: 400px;
display: inline-block;
}
You can try this example in this codesandbox.
import React, {useState} from "react";
import "./styles.css";
export default function App() {
const [toggle, setToggle]= React.useState(false)
const [width, setWidth]= React.useState('')
const showMenu = () => {
setToggle(!toggle)
if(toggle === true) {
setWidth('50px')
}else {
setWidth('500px')
}
}
return (
<div className="App">
<button onClick={showMenu}>Menu</button>
<div style={{width, border:'1px solid red'}}>
<li>text</li>
<li>text</li>
<li>text</li>
<li>text</li>
</div>
</div>
);
}
reproducing link: https://codesandbox.io/s/billowing-flower-rxdk3?file=/src/App.js:0-592
I have this list:
render() {
return (
<section className='display-question'>
<div className='wrapper'>
<ul style={{listStyleType: 'none'}}>
{/*kategoria, poziom (liceum itd), pkty, zdjecie*/}
{this.state.questions.map((question) => {
return (
<li key={question.id}>
<h3>Kategoria: {question.category}</h3>
<p>Poziom: {question.level}</p>
<p>Punkty: {question.pointAmount}</p>
<img alt='' style={{width: '20%'}} src={question.photoURL}/>
<Button onClick={this.clickHandler} style={{display: 'block', margin: 'auto'}}
bsStyle="primary" id={question.id}>Rozwiaz to zadanie kurwo
</Button>
</li>
)
})}
</ul>
</div>
</section>
)
}
I want, every time someone clicks on the button, it will take them to a different screen, showing more details. But I have no idea how to start. So far this is my App.js
import React, {Component} from 'react';
// import logo from './logo.svg';
import './App.css';
import Navbar from "./components/nav";
import Questions from './components/questions';
import {Stuff} from './components/stuff';
class App extends Component {
constructor(p) {
super(p);
this.state = {user: null};
this.checkUserState = this.checkUserState.bind(this);
}
checkUserState(user) {
this.setState({user});
}
render() {
return (
<div className="App">
<Navbar {...this}/>
{this.state.user ? <Questions/> : <Stuff/>}
</div>
);
}
}
export default App;
And this is the Questions.js file:
import React from 'react';
import firebase from 'firebase';
import {Button} from 'react-bootstrap';
class Questions extends React.Component {
constructor(props) {
super(props);
this.state = {
currentItem: '',
username: '',
questions: []
}
this.clickHandler = this.clickHandler.bind(this);
}
componentDidMount() {
const questionsRef = firebase.database().ref('Works');
questionsRef.on('value', (snapshot) => {
let questions = snapshot.val();
let newState = [];
for (let question in questions) {
newState.push({
id: question,
category: questions[question].category,
level: questions[question].level,
pointAmount: questions[question].pointAmount,
photoURL: questions[question].photoURL,
});
}
this.setState({
questions: newState
});
});
}
clickHandler() {
console.log("e");
}
render() {
return (
<section className='display-question'>
<div className='wrapper'>
<ul style={{listStyleType: 'none'}}>
{/*kategoria, poziom (liceum itd), pkty, zdjecie*/}
{this.state.questions.map((question) => {
return (
<li key={question.id}>
<h3>Kategoria: {question.category}</h3>
<p>Poziom: {question.level}</p>
<p>Punkty: {question.pointAmount}</p>
<img alt='' style={{width: '20%'}} src={question.photoURL}/>
<Button onClick={this.clickHandler} style={{display: 'block', margin: 'auto'}}
bsStyle="primary" id={question.id}>Rozwiaz to zadanie kurwo
</Button>
</li>
)
})}
</ul>
</div>
</section>
)
}
}
export default Questions;
And this is what I have for the question.js file.
import React from 'react';
export default class Question extends React.Component {
constructor(p) {
super(p);
}
render() {
return (
<React.Fragment>
<img src="" alt=""/>
</React.Fragment>
)
}
}
So how this works: I grab the list from Firebase, then I render a list with h3, some ps, img, and a button.
I want when the button is clicked, for the user to be taken to a different "screen" with more details. But I cannot see how to set it up.
Any help will be appreciated. I'm open to another suggestions. I was thinking about making it a modal, but this doesn't seem right.
The missing piece is that you don't use any routing library.
The most popular one is react-router.
Here's a basic example (from their docs), that will help you to understand the idea and help you start using it:
import React from 'react'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const Home = () => (
<div>
<h2>Home</h2>
</div>
)
const About = () => (
<div>
<h2>About</h2>
</div>
)
const Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
)
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.path}/:topicId`} component={Topic}/>
<Route exact path={match.path} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
)
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
export default BasicExample