Issue
i'm having this issue with my components, the thing is that i'm using at this moment 3 main components, one is called Page.jsx the other is called Pencil.jsx and the other is PencilCase.js.
This is my Page.jsx component
import { useState } from "react"
import { toPng } from "html-to-image"
import download from "downloadjs"
const Page = () => {
//localStorage use it with te xt
const [inputText, setText] = useState(
window.localStorage.getItem('inputText')
)
function setLocalStorage(value) {
try {
setText(value)
window.localStorage.setItem("inputText", value)
console.log(value)
} catch (error) {
console.log(error)
}
}
//localStorage use it with title
const [inputTitle, setTitle] = useState(
window.localStorage.getItem('inputTitle')
)
function setTitleStorage(value) {
try {
setTitle(value)
window.localStorage.setItem('inputTitle', value) //(key,var)
} catch (error) {
console.log(error)
}
}
const pngDownload = document.querySelector('.MainPage');
function btnDownload(){
toPng(pngDownload)
.then(dataPng =>{
download(dataPng, 'NotePad.png')
})
.catch(error=>console.log(error))
}
return (
<>
<section className="MainPage">
<main id="MainContent">
<header id="HeaderPage">
<input
type="text"
id="inputTitle"
placeholder="Insert Title"
value={inputTitle}
onChange={e => setTitleStorage(e.target.value)}
style={{color: `${inputText}`}}
/>
<h2 id="TextTitle">
{inputTitle}
</h2>
</header>
<section className="TextContainer">
<textarea
placeholder="Insert Text"
name="textarea"
id="InputText"
onChange={e => setLocalStorage(e.target.value)}
value={inputText}
style={{color: `${inputText}`}}
>
</textarea>
<p
className="ShowText">
{inputText}
</p>
</section>
</main>
</section>
<button
id="btnDownload"
onClick={btnDownload}
>
<picture id="PrintContainer">
<img id="PrintIcon"
src="print-solid.svg"
alt="Print Icon" />
</picture>
Print
</button>
</>
)
}
export default Page
I was trying to set up the text color from me PencilCase.js component.
This is my PencilCase component:
import { useState } from "react"
import Pencil from "./Pencil"
import colors from "../../common/colors.js"
const PencilCase = () => {
const [expand, setExpand] = useState(false)
const [selectedColor, setSelectedColor] = useState(null);
/*
Create useState to passing the color from pencil to pencilCase
*/
const handleColorClick = (color) => {
setSelectedColor(color);
// Save the selected color in local storage
localStorage.setItem("inputText", color);
console.log(selectedColor)
};
function handleOpen() {
setExpand(
prevValue => !prevValue
)
}
return (
<article id="PencilCaseContainer">
<section
onClick={handleOpen}
id="ShowColor"
>
<picture
id="PaletteContainer">
<figure
id="ColorPalleteBehind">
</figure>
{/* <figure id="ColorPallete">*/}
<img
id="PaletteIcon"
src="palette-solid.svg"
alt="Palette Icon" />
{/*</figure>*/}
</picture>
</section>
{expand &&
<section
id="PencilCase">
<Pencil
colors={colors.black}
onClick={() => handleColorClick(colors.black)}
/>
<Pencil
colors={colors.green}
onClick={() => handleColorClick(colors.green)}
/>
<Pencil
colors={colors.yellow}
onClick={() => handleColorClick(colors.yellow)}
/>
<Pencil
colors={colors.blue}
onClick={() => handleColorClick(colors.blue)}
/>
<Pencil
colors={colors.red}
onClick={() => handleColorClick(colors.red)}
/>
</section>}
</article>
)
}
export default PencilCase
As you can see i'v been trying to pass the seleceted color from my PencilCase component to Page component, the thing is both of them are not related.
<Pencil />
is child component of <PencilCase />
so that is why i can set the props but with Page.jsx i can not do it because neither of them are children.
This is my other component where you can see the components relation
import Page from "./Page"
import PencilCase from "./PencilCase"
const NotePad= ()=>{
return(
<>
<main className="BodyPad">
<Page />
<PencilCase />
</main>
</>
)
}
export default NotePad
Pls guys help me :c
I'v been trying to create a onClick function so anytime a <Pencil />
component is clicked the color can be saved as localStorage color and i can use it in <Page />
component to set the textColor but it is not working, i have been reading about it and i tried do it with context and provider but it doesn't worked.
Solution
It's seems the problem is inputText
state on the Parent doesn't rerender, hence it's not setting the color, AFAIK it's expected behaviour. To make input
color change and set the value to localStorage, there are two things you can do:
1. Lifting state up to the parent
const NotePad = () => {
const [inputColor, setInputColor] = useState()
return (
<main>
<Page inputColor={inputColor}/>
<PencilCase onChangeInputColor={(color) => setInputColor(color)}/>
</main>
)
}
const Page = ({inputColor}) => {
return (
<input style={{color: `${inputColor}`}} />
)
}
const PencilCase = ({onChangeInputColor}) => {
return (
<>
<Pencil onClick={() => onChangeInputColor(colors.black)}
<>
)
}
2. Share state using context
import * as React from "react";
const InputColor = React.createContext<{
inputColor: string | null;
setInputColor: (color: string | null) => void;
}>({} as any);
const useInputColor = () => React.useContext(InputColor);
const ColorProvider = ({ children }: { children: React.ReactNode }) => {
const [inputColor, setInputColor] = React.useState<string | null>(null);
return (
<InputColor.Provider value={{ inputColor, setInputColor }}>
{children}
</InputColor.Provider>
);
};
export const Context = () => {
return (
<ColorProvider>
<div>
<h3>Context</h3>
<Page />
<PencilCase />
</div>
</ColorProvider>
);
};
const Page = () => {
const { inputColor } = useInputColor();
return (
<div>
<input
defaultValue="Context"
style={inputColor ? { color: inputColor } : {}}
/>
</div>
);
};
const PencilCase = () => {
const { setInputColor } = useInputColor();
return (
<div style={{ display: "flex", gap: 10 }}>
<Pencil bgColor="red" onClick={() => setInputColor("red")} />
<Pencil bgColor="white" onClick={() => setInputColor("white")} />
<Pencil bgColor="blue" onClick={() => setInputColor("blue")} />
</div>
);
};
Here's for the demo
References:
- https://react.dev/learn/sharing-state-between-components
- https://react.dev/learn/passing-data-deeply-with-context
Answered By - Abdullah Ammar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.