Why Can't I style this react component - reactjs

I'm having a problem styling this component. I have added some styles but they are not reflecting. What might be the problem?
import React,{useContext} from 'react'
import "./display.css"
import { AppContext } from '../App'
const Display = () => {
const styles={
backgroundColor:"white"
}
const{type, stateWord,definition,synonyms}=useContext(AppContext)
return (
<div styles={styles} className='container'>
<section styles={styles}>
{stateWord && <div style={{color:"white"}}><h4> Word Type: {type}</h4>
<h4>Definition : {definition}</h4>
<h4>Synonyms:</h4>
{synonyms.map((syn)=>{
return<div><h4>{syn}</h4></div>
})}
</div>
}
</section>
</div>
)
}
export default Display

You have written styles instead of style in your divs. Should be style={styles}.
import React,{useContext} from 'react'
import "./display.css"
import { AppContext } from '../App'
const Display = () => {
const styles={
backgroundColor:"white"
}
const{type, stateWord,definition,synonyms}=useContext(AppContext)
return (
<div style={styles} className='container'>
<section style={styles}>
{stateWord && <div style={{color:"white"}}>
<h4> Word Type: {type}</h4>
<h4>Definition : {definition}</h4>
<h4>Synonyms:</h4>
{synonyms.map((syn)=>{
return<div><h4>{syn}</h4></div>
})}
</div>
}
</section>
</div>
)}
export default Display

It's because you misspelled style:
styles={styles}
should be
style={styles}

Related

content chnge via useState

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

Add an element with React, Typescript and useContext

I'm new to Typescript and not very familiar with the useContext hook. Basically, I have two simple components. I would like to add the items from my left component to the list on the right when I click on the button under them. My items have a name and description property. I just watch to display item.name on the side div on the right.
I would like to try and do it with useContext but I'm not sure where to start even after reading the documentation and a bunch of examples. They all seem too complicated for my tiny little example.
From what I understand, I need to:
Create something like AppContext.tsx
Create a context with createContext() // not sure about the arguments I have to put it in here with Typescript
Create a provider? // not sure about that either
Wrap my two components with the context provider
So any hint on the procedure would be appreciated. Thank you!
function App() {
return (
<div className="App">
<ItemList />
<ItemContainer />
</div>
);
}
My item list component:
function ItemList() {
return (
<div className="itemlist">
{items.map((item, index) => (
<div key={index}>
<div>{item.name}</div>
<div>{item.description}</div>
<button>Add to sidebar</button>
</div>
))}
</div>
);
}
And finally, my container on the right side:
function ItemContainer() {
return (
<div>
<h1>List of items</h1>
<p>Number of items: {}</p>
</div>
);
}
You can do something like this:
First create a context file named for example ItemList.context.tsx :
import React, {
createContext,
Dispatch,
FunctionComponent,
useState
} from "react";
import { Item } from "./data";
type ItemListContextType = {
itemList: Item[]; // type of your items that I declare in data.ts
setItemList: Dispatch<React.SetStateAction<Item[]>>; //React setState type
};
export const ItemListContext = createContext<ItemListContextType>(
{} as ItemListContextType
);
export const ItemListContextProvider: FunctionComponent = ({ children }) => {
const [itemList, setItemList] = useState<Item[]>([]);
return (
<ItemListContext.Provider
value={{ itemList: itemList, setItemList: setItemList }}
>
{children}
</ItemListContext.Provider>
);
};
You can then add the context provider in the parent component ( App.tsx in your example):
import "./styles.css";
import ItemList from "./ItemList";
import ItemContainer from "./ItemContainer";
import { ItemListContextProvider } from "./ItemList.context";
export default function App() {
return (
<div className="App">
<ItemListContextProvider>
<ItemList />
<ItemContainer />
</ItemListContextProvider>
</div>
);
}
and you can finally access your Item List by using the hook useContext in your two components:
for ItemList.tsx where you need to set the list (and optionally get the list to avoid putting twice an item):
import { useContext } from "react";
import { data, Item } from "./data";
import { ItemListContext } from "./ItemList.context";
const items: Item[] = data;
export default function ItemList() {
const { itemList, setItemList } = useContext(ItemListContext); // here you get your list and the method to set the list
const addItemToItemList = (item: Item) => {
//you are using the itemList to see if item is already in the itemList
if (!itemList.includes(item)) setItemList((prev) => [...prev, item]);
};
return (
<div className="itemlist">
{items.map((item, index) => (
<div style={{ marginBottom: 15 }} key={index}>
<div style={{ fontWeight: 800 }}>{item.name}</div>
<div>{item.description}</div>
<button onClick={() => addItemToItemList(item)}>
Add to sidebar
</button>
</div>
))}
</div>
);
}
And in your ItemContainer.tsx you only need the list so you can import only the setItemList from the context with useContext:
import { useContext } from "react";
import { ItemListContext } from "./ItemList.context";
export default function ItemContainer() {
const { itemList } = useContext(ItemListContext);
return (
<div style={{ flexGrow: 4 }}>
<h1 style={{ textAlign: "center" }}>List of items</h1>
<p>Number of items: {itemList.length}</p>
{itemList.length > 0 && (
<ul>
{itemList.map((item, i) => (
<li key={i}>{item.name}</li>
))}
</ul>
)}
</div>
);
}
UPDATE with a Router
It's quite the same thing you only need to wrap your browser router in the context provider if you want it to be at the highest place in your app (for a them provider or a dark mode provider for example):
export default function App() {
return (
<div className="App">
<ItemListContextProvider>
<BrowserRouter>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/itemList" component={ItemListPage} />
</Switch>
</BrowserRouter>
</ItemListContextProvider>
</div>
);
}
but I suggest you to put your provider the nearest place where your subscribers components are.
You can for example create a page component that will be use in the browser router and put in it the provider, like this:
ItemListPage.tsx
import React, { FunctionComponent } from "react";
import ItemList from "./ItemList";
import ItemContainer from "./ItemContainer";
import { Link } from "react-router-dom";
import { ItemListContextProvider } from "./ItemList.context";
const ItemListPage: FunctionComponent = () => {
return (
<>
<ItemListContextProvider>
<h1 style={{ alignSelf: "flex-start" }}>ITEM LIST</h1>
<Link to="/">homePage</Link>
<div className="itemListPage">
<ItemList />
<ItemContainer />
</div>
</ItemListContextProvider>
</>
);
};
export default ItemListPage;
and of course you remove the context provider in your App.tsx and it should look like :
App.tsx
import React, { FunctionComponent } from "react";
import ItemList from "./ItemList";
import ItemContainer from "./ItemContainer";
import { Link } from "react-router-dom";
import { ItemListContextProvider } from "./ItemList.context";
const ItemListPage: FunctionComponent = () => {
return (
<>
<ItemListContextProvider>
<h1 style={{ alignSelf: "flex-start" }}>ITEM LIST</h1>
<Link to="/">homePage</Link>
<div className="itemListPage">
<ItemList />
<ItemContainer />
</div>
</ItemListContextProvider>
</>
);
};
export default ItemListPage;

How to hide a button when I click the button in react using functional components

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

how to re-render all related components with i18n strings once language is changed

this main App function has a custom hook that will trigger when the button is cliked:
import React, { useEffect } from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom'
import HomeScreen from './Screens/HomeScreen'
import './App.css';
import { useCurrentLang } from './utils/useCurrentLang'
import {strings as engstrings} from './res/lang/eng/strings'
function App() {
const currentStrings = useCurrentLang(engstrings);
return (
<BrowserRouter>
<div className="grid-container">
<header className="header">
<div className="brand">
<Link to="/" >
</Link>
</div>
<div className="header-side">
{currentStrings.currentlang.subtitle}
</div>
<div className="header-right">
<button {...currentStrings}>
{currentStrings.currentlang.traduction}
</button>
</div>
<div>
</div>
</header>
<main className="main">
<div className="content">
<Route path="/" exact={true} component={HomeScreen} />
</div>
</main>
<footer className="footer">
© 2020
</footer>
</div>
</BrowserRouter>
);
}
export default App;
However this component function that is routed from App also needs to use the same reference of the hook object found in App:
import React from 'react';
import terminalImage from '../res/images/GNOMETerminalIcon.png';
import {useCurrentLang} from '../utils/useCurrentLang'
import {strings as engstrings} from '../res/lang/eng/strings'
const { Link } = require("react-router-dom");
function HomeScreen() {
const currentStrings = useCurrentLang(engstrings);
return <div className="home">
<ul className="menu-list">
<li>
<div className="about-link section">
<Link to="/about">{currentStrings.currentlang.about}</Link>
</div>
</li>
<li>
<div className="projects-link section">
<Link to="/about">{currentStrings.currentlang.about}</Link>
</div>
</li>
<li>
<div className="contacts-link section">
<Link to="/about">{currentStrings.currentlang.about}</Link>
</div>
</li>
<li>
<div className="suggestions-link section">
<Link to="/about">{currentStrings.currentlang.about}</Link>
</div>
</li>
</ul>
<div className="home-main-image">
<img src={terminalImage} />
</div>
</div>
}
export default HomeScreen;
Is it possible for both function to rerender when the hook on App is triggered? if yes, how?
Edit: currentLang hook:
import {useState} from 'react'
import {strings as frstrings} from '../res/lang/fr/strings'
import {strings as engstrings} from '../res/lang/eng/strings'
export const useCurrentLang = initialState => {
if(initialState === 0){
initialState = engstrings
}
const [currentlang, setLang] = useState(initialState);
return {
currentlang: currentlang,
onClick: () => {
if(currentlang === engstrings){
setLang(frstrings)
} else {
setLang(engstrings)
}
}
}
}
Problem
The main problem you're facing is one part of your React Tree has no idea that the language has changed.
Solution
Use a Language Context which provides the updates to all your React tree and wrap it on the top of the application. In layman terms, now your app is on listening mode whenever lang changes. So basically, what React does now is whenever lang changes, it will find wherever lang is used from the context and update the component.
Docs on React context here
import React from 'react'
// import {strings as frstrings} from '../res/lang/fr/strings'
// import {strings as engstrings} from '../res/lang/eng/strings'
const lang = {
// in this way, you could dynamically add lang
// later on which worrying about if-elses in your component
en: {
hello: 'hello'
},
fr: {
hello: 'bonjour',
},
}
const langDict = (key) => lang[key]
const LanguageContext = React.createContext(null);
function LanguageProvider({ initialState = 'en', children }) {
const [lang, setLang] = React.useState(initialState);
return (
<LanguageContext.Provider value={[langDict(lang), setLang]}>
{children}
</LanguageContext.Provider>
)
}
function useLanguage() {
return React.useContext(LanguageContext);
}
export default function AppWrapper() {
return (
<LanguageProvider>
<App />
</LanguageProvider>
)
}
function App() {
const [lang, setLang] = useLanguage();
return (
<div>
<h1>{lang.hello}</h1>
<button onClick={() => setLang('fr')}>French</button>
<button onClick={() => setLang('en')}>English</button>
</div>
)
}

how to change background color when I click the button using react hooks

I am working on React project, In that I have App.js component, in that component I have button Now please tell me how to change button background color and button text color by using react hooks
This is App.js
import React, { useState } from 'react';
import './App.css';
function App() {
return (
<div className="App">
<button className='btn btn-primary'>Click here</button>
</div>
);
}
export default App;
try this
function App() {
const [color,setColor]=useState('red');
const [textColor,setTextColor]=useState('white');
return (
<div className="App">
<button style={{background:color,color:textColor}} className='btn btn-primary' onClick={()=>{setColor("black");setTextColor('red')}}>Click here</button>
</div>
);
}
export default App;
OR
check link : https://stackblitz.com/edit/react-x7mevv
App.js
function App() {
const [toggle,setToggle] = React.useState(false);
const toggleIt =()=>{
setToggle(!toggle)
}
return (
<div className="App">
<button onClick={toggleIt}>{toggle?'Hide':'Show'}</button>
<div className={toggle&&'body-color'}>
Body
</div>
</div>
);
}
class in App.css
.body-color{
background: coral;
height:100vh;
}

Resources