i'm just starting to learn react, where did i go wrong, can't undestand what am i doing wrong this is my problem
my goal: to ensure that the picture changes as true / false
maybe I am not passing props correctly??
it's my code:
import React, { useState, useEffect } from 'react'
import styles from './styles.module.scss'
import { Link } from 'react-router-dom'
import classNames from 'classnames'
import DjalKokildak from '../../../../assets/images/DjalKokildak.png'
import Turpachaty from '../../../../assets/images/Turpachaty.png'
const Fields = ({image}) => {
const data = [
{
img: {
true : DjalKokildak,
false : Turpachaty
}
}
]
console.log(data)
const [image, setImage] = useState(true)
return (
<div className={styles.container}>
<div className={styles.wrapper}>
<div className={styles.line} />
<div className={styles.contentBlock}>
<div className={styles.titleBlock}>
<h1 className={styles.title}>месторождения</h1>
<p className={styles.text}>“Джал-Кокильдак” и “Турпачаты”</p>
<Link to='/' className={styles.link}>подробнее</Link>
</div>
<div className={styles.actionBlock}>
<button onClick={() => setImage(false)} className={styles.button}>след</button>
<div className={styles.imgBlock}>
{data.map(item => item.img === img && (
<img src={item.img[setImage]}>{image}</img>
))
}
</div>
<button onClick={() => setImage(true)} className={styles.button}>пред</button>
</div>
</div>
</div>
</div>
)
}
export default Fields
Related
I need to parse data from modal window (Modalbuy.js) to parent component (Page.js) and then to another child, but my Context Provider doesn't see changed data.Despite that fact, if I ask to console.log not in context.provider brackets, but still in parent component, I get my data logs right
Modalbuy.js
import React, {useState} from "react";
import "./modal.css";
import { DataBuyContext } from "../../page/page";
const Modalbuy = ({active, setActive,price}) => {
const [inputVolume, setInputVolume] = useState("")
function saveInput(event) {
setInputVolume(event.target.value)
console.log(inputVolume)
}
const {dataBuy, setDataBuy} = React.useContext(DataBuyContext)
function addBuy() {
setDataBuy([...dataBuy,{side: "BUY", price:{price},volume: {inputVolume},timestamp: new Date().toLocaleTimeString()}])
// console.log(dataBuy)
}
return (
<div className={active ? "modal active" : "modal"} onClick={() => setActive(false)}>
<div className="modal__content" onClick={e => e.stopPropagation()}>
<header>Make order</header>
<p>BUY {price}</p>
<input placeholder="Volume" value={inputVolume} onChange={saveInput}></input>
<div>
<button onClick = {addBuy}>Ok</button>
<button onClick={() => setActive(false)} >Cancel</button>
</div>
</div>
</div>
)
}
export default Modalbuy;
Page.js
import React, {useState} from 'react'
import Trading from '../trading/Trading'
import Archive from '../archive/Archive'
import './page.css';
export const DataBuyContext = React.createContext({})
const Page = () => {
const [dataBuy, setDataBuy] = useState([{}])
const [toggleState, setToggleState] = useState(1)
const toggleTab = (index) =>{
setToggleState(index);
}
console.log(dataBuy)
return (
<DataBuyContext.Provider value = {{dataBuy, setDataBuy}}>
<div className="container">
<div className="block-tabs">
<button
className={toggleState === 1 ? "tabs active-tabs" : "tabs"}
onClick={() => toggleTab(1)}>
Trading
</button>
<button
className={toggleState === 2 ? "tabs active-tabs" : "tabs"}
onClick={() => toggleTab(2)}>
Archive
</button>
</div>
<div className="content-tabs">
<div
className={toggleState === 1 ? "content active-content" : "content"}>
<Trading />
</div>
<div
className={toggleState === 2 ? "content active-content" : "content"}>
<Archive dataBuy= {dataBuy} />
</div>
</div>
</div>
</DataBuyContext.Provider>
);
}
export default Page;
And Archive.js child component, where I want to transport data
import React, {useState} from 'react';
import './archive.css';
import Table from './Table';
const Archive = (dataBuy) => {
const [rows, setRows] = useState(dataBuy)
console.log(rows)
return (
<Table dataBuy = {rows}/>
)
}
export default Archive;
App.js
import './App.css';
import React from 'react';
import Page from './components/page/page'
function App() {
return (
<div className="App">
<Page/>
</div>
);
}
export default App;
import React, { useState } from 'react';
import NavBar from "../../components/navBar/navbar";
import "./profile.scss"
import add from './Images/add.png'
import added from './Images/added.png'
const Profile = () => {
return (
<div className="navbar-display">
<NavBar/>
<div className="right" >
<img id='imageid' src={add} alt='' onClick={''}/>
</div>
</div>
)
}
export default Profile;
<div className="right" >
<img id='imageid' src={add} alt='' onClick={''}/>
</div>
This is the section im having troubles with. Ive tried lots of online methods but constantly ran into errors and cant seem to find a definitive way to onclick change image with ReactJS
just simply use the useState to keep track of your image, something like this:
import React, { useState } from "react";
import NavBar from "../../components/navBar/navbar";
import "./profile.scss";
import add from "./Images/add.png";
import added from "./Images/added.png";
const Profile = () => {
const [image, setImage] = useState("left");
const handleClick = () => {
if (image === "left") {
setImage("right");
} else {
setImage("left");
}
};
return (
<div className="navbar-display">
<NavBar />
<div className="right">
<img
id="imageid"
src={image === "left" ? add : added}
alt=""
onClick={() => handleClick()}
/>
</div>
</div>
);
};
I ended up fixing this issue by using state as above mentioned like this. Thank you for the reply <3
const [isFollowed, setIsFollowed] = useState(false);
const [isFollowedtext, setIsFollowedtext] = useState(false);
const followHandler = () => {
setIsFollowed(!isFollowed);
setIsFollowedtext(!isFollowedtext);
};
<div className="right" onClick={followHandler}>
{isFollowed ?
<p>Connected with user!</p> : <p>Connect with user!</p>}
{isFollowedtext ?
<img src={added} alt="" /> : <img src={add} alt="" />}
</div>
I want to load a component depending in what page are the user.
Pages:
Executables
Shop
In the main screen I have a sidebar with 2 icons that i want the primary button sets the Executables Page and the second shop page.
Like having a web page with no routes and rendering components depending the user selection.
My code:
Components/Dashboard.tsx
import styled from "styled-components"
import Executable from "./Executable"
import Navbar from "./Navbar"
import { useEffect } from "react"
type EntryProps = {
section: string
}
const Dashboard = ({ section }: EntryProps) => {
var TypeElement
useEffect(() => {
if (section === "executables") {
TypeElement = (
<div className="grid">
<div className="row">
<Executable />
</div>
</div>
)
}
}, [section])
return (
<Section>
<Navbar />
{TypeElement}
</Section>
)
}
Components/Sidebar.tsx
import styled from "styled-components"
import { FaBars } from "react-icons/fa"
import { BsFileEarmarkBinary } from "react-icons/bs"
import { BiLogOut } from "react-icons/bi"
import { AiOutlineShoppingCart } from "react-icons/ai"
import { IoMdSettings } from "react-icons/io"
import { useState } from "react"
type SidebarProps = {
section: string
setSection: Function
}
const Sidebar = ({ section, setSection }: SidebarProps) => {
const [disabled, setDisabled] = useState(true)
const handleDisabled = () => setDisabled(!disabled)
return (
<Aside id="aside">
<div
className={disabled ? "brand center" : "brand"}
onClick={handleDisabled}
>
<FaBars />
</div>
<ul className="links">
<li>
<BsFileEarmarkBinary />
<span
className={disabled ? "disabled" : ""}
onClick={(e) => {
console.log("Executables")
setSection("executables")
}}
>
Executables
</span>
</li>
<li>
<AiOutlineShoppingCart />
<span
className={disabled ? "disabled" : ""}
onClick={(e) => {
e.preventDefault()
setSection("shop")
}}
>
Shop
</span>
</li>
<li>
<IoMdSettings />
<span
className={disabled ? "disabled" : ""}
onClick={setSection("settings")}
>
Settings
</span>
</li>
</ul>
<div className="logout">
<BiLogOut />
</div>
</Aside>
)
}
Pages/DashboardPage.tsx
import styled from "styled-components"
// Components
import Sidebar from "../components/Sidebar"
import Rightsidebar from "../components/Rightsidebar"
import Dashboard from "../components/Dashboard"
import { useState } from "react"
const DashboardPage = () => {
const [page, setPage] = useState("executables")
const setSection = (name: string) => {
setPage(name)
}
return (
<Div>
<Sidebar section={page} setSection={setSection} />
<Dashboard section={page} />
<Rightsidebar />
</Div>
)
}
You are changing the value of TypeElement conditionally according to the value of the section. TypeElement is not a state, so after changing the value of the TypeElement component is not rerendered, and the updated value is not showing on the UI. Here conditional rendering might be a good solution.
<Section>
<Navbar />
{section==='executables'? <Executable />: <Shop/>}
</Section>
Okay so as you can tell,I am building a recipe app where in each recipe detail page, I can rate the the recipe...but now the problem is that when I rate one recipe now, the same rating is set for all the other recipes as well. Any idea how to fix that? Apreciate any advice...thanks so much :))
Details.js
import { useParams } from 'react-router-dom';
import './Details.css';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import Image from './vitaminDfood-1132105308-770x553.jpg';
import {Link} from 'react-router-dom'
import ReactStars from 'react-rating-stars-component'
import { RecipeContext } from './RecipeContext';
import { useContext } from 'react';
function Details() {
const [details, setDetails] = useState([]);
const { recipeId } = useParams();
const{recipes,setRecipes}=useContext(RecipeContext)
const initialRatings = JSON.parse(localStorage.getItem("rating") || "[]");
const[rating,setRating]=useState(initialRatings)
useEffect(() => {
axios
.get(`https://cookbook.ack.ee/api/v1/recipes/${recipeId}`)
.then((res) => setDetails(res.data));
});
useEffect(() => {
localStorage.setItem("rating", JSON.stringify(rating));
}, [rating])
const ratingChanged = (newRating) => {
var rate={
score:newRating
}
setRating(newRating)
axios.post(`https://cookbook.ack.ee/api/v1/recipes/${recipeId}/ratings`,rate)
.then((res) => {
console.log(res.data)
setRecipes(recipes)
})
};
return (
<>
<div className="details">
<div className="food-photo">
<img src={Image} alt="" />
<Link to="/"> <i className="fas fa-arrow-left arrow"></i></Link>
<h1>{details.name}</h1>
</div>
<div className="star-line">
{new Array(rating).fill(null).map(() => (
<i className="fas fa-star stari"/>
))}
<p className="duration"><i className="far fa-clock"></i>{details.duration}<span>min.</span></p>
</div>
<p className="info">{details.info}</p>
<h1 className="ingredience">Ingredience</h1>
<div className="ing">{details.ingredients}</div>
<h1 className="ingredience">Příprava</h1>
<p className="description">{details.description}</p>
</div>
<div className="stars">
<ReactStars
classNames="star"
size={48}
onChange={ratingChanged}
count={5}
value={1}
edit
/>
</div>
</>
);
}
export default Details;
You have a couple options:
Store a different localStorage key for each recipe
Just have one large "ratings" key in localStorage and make that an object keyed off of your recipeId.
I think the first option is the most straightforward and can be accomplished with these minor modifications:
const initialRatings = JSON.parse(localStorage.getItem(`ratings-${recipeId}`) || "[]");
useEffect(() => {
localStorage.setItem(`ratings-${recipeId}`, JSON.stringify(rating));
}, [rating, recipeId])
By default I am trying to show button, Now I am trying to hide button when I click the buton in react using functional components.
This is my code
This is App.js
import React, { useState } from 'react';
import Parent from './Parent/Parent';
import './App.css';
function App() {
return (
<div className="App">
<Parent></Parent>
</div>
);
}
export default App;
This is Parent.js
import React, { useState } from 'react';
import './Parent.css';
const Parent = () => {
const [show, hide] = useState(true)
const hideButton = () => {
hide(false)
}
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<div className='one'>
<button show ={show} onClick={hideButton} className='btn btn-primary'>Click here</button>
</div>
</div>
</div>
</div>
)
}
export default Parent
You need to do ternary condition to show and hide value:
{show && <button onClick={hideButton} className='btn btn-primary'>Click here</button>}
Full code:
import React, { useState } from "react";
import "./styles.css";
const Parent = () => {
const [show, hide] = useState(true);
const hideButton = () => {
hide(false);
};
return (
<div className="container">
<div className="row">
<div className="col-12">
<div className="one">
{show && (
<button onClick={hideButton} className="btn btn-primary">
Click here
</button>
)}
</div>
</div>
</div>
</div>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Parent />
</div>
);
}
Here is the demo: https://codesandbox.io/s/romantic-newton-1wvl1?file=/src/App.js:0-678