import axios from 'axios'
import React from 'react'
import { useState, useEffect } from 'react'
import {useHistory} from 'react-router-dom'
import Spinner from './Spinner'
const Home = () => {
const [search, setSearch] = useState({
category: 'All',
searchBar: '',
})
const handleCategory = e => {
setSearch({...search, category: e.target.id})
}
const handleSearch = e => {
setSearch({...search, searchBar: e.target.value})
}
// This only works for the categories
const filteredPreviews = search.category === 'All'
? previews
: previews.filter(preview => preview.category === search.category)
return (
<div className="container">
<section className="main-nav">
<div className="main-nav-content">
<ul className='categories'>
<li><a onClick={(e) => handleCategory(e)} id='All'>All</a></li>
<li><a onClick={(e) => handleCategory(e)} id='Action'>Action</a></li>
<li><a onClick={(e) => handleCategory(e)} id='Adventure'>Adventure</a></li>
<li><a onClick={(e) => handleCategory(e)} id='Survival'>Survival</a></li>
<li><a onClick={(e) => handleCategory(e)} id='Simulation'>Simulation</a></li>
<li><a onClick={(e) => handleCategory(e)} id='Racing'>Racing</a></li>
</ul>
<ul className='main-input'>
<li>
<i className="fas fa-search"></i>
<input type="text" onChange={(e) => handleSearch(e)} placeholder="Search Games..." />
</li>
</ul>
</div>
</section>
<section className="games">
{
filteredPreviews.map(preview => (
<div>
<h3>{preview.title}</h3>
<p>{preview.category}</p>
</div>
))}
</section>
</div>
)
}
export default Home
Sample Data
const previews = [
{
title: "Red Dead Redemption 2",
category: "Survival",
},
{
title: "FEAR",
category: "Horror",
},
{
title: "Battlefield 1",
category: "Action",
},
];
So I have a function that handles the current category that the user clicks on and displays the previews accordingly, but I cannot figure out how I let the user use the search input too, I tried using || conditionals and other things but in the end I couldnt figure it out, any help is appreciated!
import React from "react";
import { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
const previews = [
{
title: "Red Dead Redemption 2",
category: "Survival"
},
{
title: "FEAR",
category: "Horror"
},
{
title: "Battlefield 1",
category: "Action"
}
];
const Home = () => {
const [search, setSearch] = useState({
category: "All",
searchBar: ""
});
const handleCategory = (e) => {
setSearch({ ...search, category: e.target.id });
};
const handleSearch = (e) => {
setSearch({ ...search, searchBar: e.target.value,category :'' });
};
// This only works for the categories
// Now this works for search too
const filteredPreviews = () => {
const { category, searchBar } = search;
if (category === "All" || (searchBar && searchBar === "All")) {
return previews;
}
const filtered = previews.filter((preview) => {
if (
preview.category === category ||
(searchBar && searchBar === preview.category)
) {
return preview;
}
});
return filtered;
};
return (
<div className="container">
<section className="main-nav">
<div className="main-nav-content">
<ul className="categories">
<li>
<a onClick={(e) => handleCategory(e)} id="All">
All
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Action">
Action
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Adventure">
Adventure
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Survival">
Survival
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Simulation">
Simulation
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Racing">
Racing
</a>
</li>
</ul>
<ul className="main-input">
<li>
<i className="fas fa-search"></i>
<input
type="text"
onChange={(e) => handleSearch(e)}
placeholder="Search Games..."
/>
</li>
</ul>
</div>
</section>
<section className="games">
{filteredPreviews().map((preview) => (
<div>
<h3>{preview.title}</h3>
<p>{preview.category}</p>
</div>
))
}
</section>
</div>
);
};
export default Home;
import axios from "axios";
import React from "react";
import { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
const previews = [
{
title: "Red Dead Redemption 2",
category: "Survival"
},
{
title: "FEAR",
category: "Horror"
},
{
title: "Battlefield 1",
category: "Action"
}
];
const Home = () => {
const [search, setSearch] = useState({
category: "All",
searchBar: ""
});
const handleCategory = (e) => {
setSearch({ ...search, category: e.target.id });
};
const handleSearch = (e) => {
setSearch({ ...search, searchBar: e.target.value });
};
// This only works for the categories
// Now this works for search too
const filteredPreviews = () => {
const { category, searchBar } = search;
if (category === "All" || (searchBar && searchBar === "All")) {
return previews;
}
const filtered = previews.filter((preview) => {
if (
preview.category === category ||
(searchBar && searchBar === preview.category)
) {
return preview;
}
});
return filtered;
};
return (
<div className="container">
<section className="main-nav">
<div className="main-nav-content">
<ul className="categories">
<li>
<a onClick={(e) => handleCategory(e)} id="All">
All
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Action">
Action
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Adventure">
Adventure
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Survival">
Survival
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Simulation">
Simulation
</a>
</li>
<li>
<a onClick={(e) => handleCategory(e)} id="Racing">
Racing
</a>
</li>
</ul>
<ul className="main-input">
<li>
<i className="fas fa-search"></i>
<input
type="text"
onChange={(e) => handleSearch(e)}
placeholder="Search Games..."
/>
</li>
</ul>
</div>
</section>
<section className="games">
{filteredPreviews().map((preview) => (
<div>
<h3>{preview.title}</h3>
<p>{preview.category}</p>
</div>
))}
</section>
</div>
);
};
export default Home;
Related
I have a component that is a modal for login, but I'm not able to call it this is the code of the component:
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
const INITIAL_USER = {
email: '',
password: ''
}
const ModalLogin = () => {
const [user, setUser] = React.useState(INITIAL_USER);
const [disabled, setDisabled] = React.useState(true);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState('');
const [modalIsOpen, setIsOpen] = React.useState(false);
function openModal() {
setIsOpen(true);
}
function closeModal() {
setIsOpen(false);
}
React.useEffect((modal) => {
const isUser = Object.values(user).every(el => Boolean(el));
isUser ? setDisabled(false) : setDisabled(true)
}, [user]);
const handleChange = (e) => {
const { name, value } = e.target;
setUser(prevState => ({ ...prevState, [name]: value }));
}
const handleSubmit = async e => {
e.preventDefault();
try {
setLoading(true);
setError('');
const url = `${baseUrl}/api/login`;
const payload = { ...user };
const response = await axios.post(url, payload);
handleLogin(response.data);
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
const customStyles = {
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
transform: 'translate(-50%, -50%)'
}
};
return (
<Modal
isOpen={modalIsOpen}
style={customStyles}
onRequestClose={closeModal}
>
<div className="theme_login">
<div className="theme_login_box radius">
<header>
<h1>Fazer Login:</h1>
<p>Informe seu nome e e-mail para fazer login e acessar seus pedidos.</p>
</header>
<form method="POST" onSubmit={handleSubmit}>
<input className="radius" type="email" name="email" value={user.email} onChange={handleChange} placeholder="E-mail:" />
<input className="radius" type="password" name="password" value={user.password} onChange={handleChange} placeholder="Senha:" />
<button className="btn transition radius icon-success" type="submit" href="/" title="Minha conta">Fazer Login</button>
</form>
Esqueci minha senha
</div>
</div>
</Modal>
)
};
export default ModalLogin;
I want to call him through my StaticHeader.js:
import React from 'react';
import Link from "next/link";
import Router, { useRouter } from 'next/router';
import NProgress from 'nprogress';
import { handleLogout } from '../../utils/auth';
import ModalLogin from './ModalLogin';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
Router.onRouteChangeStart = () => NProgress.start();
Router.onRouteChangeComplete = () => NProgress.done();
Router.onRouteChangeError = () => NProgress.done();
const StaticHeader = ({ user }) => {
const router = useRouter();
const [menuActive, setMenuActive] = React.useState(false);
const [search, setSearch] = React.useState({ search: '' });
//console.log(user)
const isRoot = user && user.role == 'root';
const isAdmin = user && user.role == 'admin';
const isRootOrAdmin = isRoot || isAdmin;
const [modalIsOpen, setIsOpen] = React.useState(false);
function openModal() {
setIsOpen(true);
}
function closeModal() {
setIsOpen(false);
}
const isActive = (route) => {
return route == router.pathname;
}
const handleOnChange = (e) => {
const { name, value } = e.target;
setSearch(prevState => ({ ...prevState, [name]: value }))
}
const handleSearch = (e) => {
Router.push({
pathname: '/products',
query: { term: search.search }
})
}
const menuToggle = () => {
setMenuActive(!menuActive)
}
const customStyles = {
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
transform: 'translate(-50%, -50%)'
}
};
return (
<header className="main_header">
<div className="container">
<div className="main_header_nav">
<div className="main_header_nav_logo">
<a href="" title="WdpShoes | Home">
<img alt="logo" title="logo menu" src="/css/themes/logo/wdpshoes_logo_white.png" />
</a>
</div>
<div className="main_header_nav_search">
<form action="" method="post" className="radius">
<input type="text" name="s" placeholder="Pesquisar na loja:" />
<button className="icon-search icon-notext transition"></button>
</form>
</div>
<div className="main_header_nav_menu">
<a className="icon-cart icon-notext transition main_header_nav_menu_cart" href="/cart"><span>3</span></a>
<div className="main_header_nav_menu_user">
<a href="#" title="#" className="icon-user main_header_nav_menu_user_a radius transition" onClick={openModal} >
{modalIsOpen && <ModalLogin/>}
Login</a>
<nav className="radius">
Meus Pedidos
Meus Pedeidos
Meus endereços
Sair
</nav>
</div>
</div>
</div>
<ul className="main_header_departments">
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_deprtaments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
</ul>
</div>
</header>
);
}
export default StaticHeader;
What do I need to do for this modal to appear in my header when clicking on login?
I believe it will be necessary to send the functions through the props I tried a few times without success please could someone help solve this problem?
I have a component that calls to local storage and want to test it with jestJS. As far as I can tell jest does not support calls to localStorage.
This is the component that I need to have tests for:
const NavBar: React.FC = () => {
const history = useHistory();
const handleCLick = () => {
localStorage.clear();
history.push('/login');
};
return (
<div>
<header>
<div className="banner">
<div className="container">
<img
className="icon "
alt="icon"
title="icon"
src={favicon57}
/>
<p>Official website of the Stuff</p>
</div>
</div>
<nav className="navbar navbar-expand-md navbar-dark fixed-top">
<div className="container">
<div className="navbar-header">
<img
className="logo "
alt="logo"
title="Logo"
src={Blah}
/>
</div>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarCollapse"
aria-controls="navbarCollapse"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarCollapse">
<ul className="navbar-nav ml-auto">
{isTokenAdmin() ? (
<li className="nav-item">
<a id="nav-users" className="nav-link" href={ADMIN_URL}>
View Users
</a>
</li>
) : (
<div> </div>
)}
{isTokenActive() ? (
<li className="nav-item">
<a id="nav-log-out" className="nav-link" href={APP_URL}>
Locations
</a>
</li>
) : (
<div> </div>
)}
{isTokenActive() ? (
<li className="nav-item">
<a
id="nav-log-out"
className="nav-link"
href={LOGIN_URL}
onClick={() => {
handleCLick();
}}
>
Logout
</a>
</li>
) : (
<div> </div>
)}
</ul>
</div>
</div>
</nav>
</header>
</div>
);
};
export default NavBar;
As you can see I am rendering the buttons based off of the token that I have stored in localStorage. How would you get this to 100% test coverage?
EDIT:
The code for the functions to get the token are:
export const isTokenActive = (): boolean => {
const userToken: string | null = localStorage.getItem('exp');
if (typeof userToken === 'string') {
return new Date().getTime() < Number.parseInt(userToken, 10);
}
return false;
};
export const isTokenAdmin = (): boolean => {
const userToken: string | null = localStorage.getItem('access_token');
if (typeof userToken === 'string') {
const decodedToken: TokenDetails = jwt_decode(userToken);
return decodedToken.authorities[0] === 'ROLE_Administrator';
}
return false;
};
You are correct that Jest does not support calls to localStorage. It is not a browser and doesn't implement localStorage.
The solution is to mock your own fake localStorage support like below:
browserMocks.js
const localStorageMock = (function() {
let store = {}
return {
getItem: function(key) {
return store[key] || null
},
setItem: function(key, value) {
store[key] = value.toString()
},
removeItem: function(key) {
delete store[key]
},
clear: function() {
store = {}
}
}
})()
Object.defineProperty(window, 'localStorage', {
value: localStorageMock
})
Jest config (can be inside your package.json)
"jest": {
"setupFiles": [
"<rootDir>/__jest__/browserMocks.js",
Then to see if localstorage has been called you can spy on it like this:
describe('signOutUser', () => {
it('should sign out a user', async () => {
const spyLoStoRemove = jest.spyOn(localStorage, 'removeItem')
await signOutUser()
expect(spyLoStoRemove).toHaveBeenCalled()
expect(spyLoStoRemove).toHaveBeenCalledTimes(2)
})
})
hi friends i'm having a problem if someone can help me i'll be very grateful, i can't find out why my modal doesn't close using shouldCloseOnOverlayClick = {true} and even without using it it doesn't close either I'll put the code:
components/_App/ModalLogin.js
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
import catchErrors from '../../utils/catchErrors';
const INITIAL_USER = {
email: '',
password: ''
}
const ModalLogin = ({isOpen, close }) => {
const [user, setUser] = React.useState(INITIAL_USER);
const [disabled, setDisabled] = React.useState(true);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState('');
React.useEffect((modal) => {
const isUser = Object.values(user).every(el => Boolean(el));
isUser ? setDisabled(false) : setDisabled(true)
}, [user]);
const handleChange = (e) => {
const { name, value } = e.target;
setUser(prevState => ({ ...prevState, [name]: value }));
}
const handleSubmit = async e => {
e.preventDefault();
try {
setLoading(true);
setError('');
const url = `${baseUrl}/api/login`;
const payload = { ...user };
const response = await axios.post(url, payload);
handleLogin(response.data);
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
const customStyles = {
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
transform: 'translate(-50%, -50%)'
}
};
console.log(close)
return (
<Modal
isOpen={isOpen}
style={customStyles}
onRequestClose={close}
shouldCloseOnOverlayClick={true}
>
<div className="">
<div className="theme_login_box radius">
<header>
<h1>Fazer Login:</h1>
<p>Informe seu nome e e-mail para fazer login e acessar seus pedidos.</p>
</header>
<form method="POST" onSubmit={handleSubmit}>
<input className="radius" type="email" name="email" value={user.email} onChange={handleChange} placeholder="E-mail:" />
<input className="radius" type="password" name="password" value={user.password} onChange={handleChange} placeholder="Senha:" />
<button className="btn transition radius icon-success" type="submit" href="/" title="Minha conta" >Fazer Login</button>
</form>
Esqueci minha senha
</div>
</div>
</Modal>
)
};
export default ModalLogin;
my file where I invoke the modal:
components/_App/StaticHeader.js
import React from 'react';
import Link from "next/link";
import Router, { useRouter } from 'next/router';
import NProgress from 'nprogress';
import { handleLogout } from '../../utils/auth';
import ModalLogin from './ModalLogin';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
Router.onRouteChangeStart = () => NProgress.start();
Router.onRouteChangeComplete = () => NProgress.done();
Router.onRouteChangeError = () => NProgress.done();
const StaticHeader = ({ user }) => {
const router = useRouter();
const [menuActive, setMenuActive] = React.useState(false);
const [search, setSearch] = React.useState({ search: '' });
//console.log(user)
const isRoot = user && user.role == 'root';
const isAdmin = user && user.role == 'admin';
const isRootOrAdmin = isRoot || isAdmin;
const [modalIsOpen, setIsOpen] = React.useState(false);
function openModal() {
setIsOpen(true);
}
function closeModal() {
setIsOpen(false);
}
const isActive = (route) => {
return route == router.pathname;
}
const handleOnChange = (e) => {
const { name, value } = e.target;
setSearch(prevState => ({ ...prevState, [name]: value }))
}
const handleSearch = (e) => {
Router.push({
pathname: '/products',
query: { term: search.search }
})
}
const menuToggle = () => {
setMenuActive(!menuActive)
}
return (
<header className="main_header">
<div className="container">
<div className="main_header_nav">
<div className="main_header_nav_logo">
<a href="" title="WdpShoes | Home">
<img alt="logo" title="logo menu" src="/css/themes/logo/wdpshoes_logo_white.png" />
</a>
</div>
<div className="main_header_nav_search">
<form action="" method="post" className="radius">
<input type="text" name="s" placeholder="Pesquisar na loja:" />
<button className="icon-search icon-notext transition"></button>
</form>
</div>
<div className="main_header_nav_menu">
<a className="icon-cart icon-notext transition main_header_nav_menu_cart" href="/cart"><span>3</span></a>
<div className="main_header_nav_menu_user">
<a href="#" title="#" className="icon-user main_header_nav_menu_user_a radius transition" onClick={openModal} >
{modalIsOpen && <ModalLogin isOpen={openModal} close={closeModal}/> }
Login</a>
<nav className="radius">
Meus Pedidos
Meus Pedeidos
Meus endereços
Sair
</nav>
</div>
</div>
</div>
<ul className="main_header_departments">
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_deprtaments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
<li className="main_header_departments_li">
Departamento
<ul className="main_header_departments_li_ul">
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
<li className="main_header_departments_li_ul_li">Categoria</li>
</ul>
</li>
</ul>
</div>
</header>
);
}
export default StaticHeader;
What could I be changing to make my modal work as expected if someone can help me thanks
The issue is that you have encapsulated your modal inside the <a /> tag and in there you have an onClick which calls openModal. Once you click on "close" inside your modal the event propagates and triggers the click on <a /> tag.
To fix the issue just pull put the <Modal /> outside of your <a /> tag.
<a href="#" title="#" className="icon-user main_header_nav_menu_user_a radius transition" onClick={openModal} >Login</a>
{modalIsOpen && <ModalLogin isOpen={modalIsOpen} close={closeModal}/> }
In this line:
{modalIsOpen && <ModalLogin isOpen={openModal} close={closeModal}/> }
The isOpen property should receive a boolean value but instead is receiving a function (openModal). The correct value is isOpen={modalIsOpen}
I'm trying to make a list of jokes but it is saying " TypeError: data.posts.map is not a function ".
I used before same code but different API and it was working.
In console it is showing those posts but on app i get error saying that " data.posts.map "
Can anyone help me?
Thanks
This is my code:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const PostArea = () => {
const [like, showLike] = useState(false);
const [color, setColor] = useState('#000');
const likePrint = () => {
showLike(!like);
}
const [data, setPost] = useState({ posts: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios('https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40');
console.log({ posts: result.data });
setPost({ posts: result.data });
};
fetchData();
}, []);
return (
<div>
{data.posts && data.posts.map(({ id, setup, delivery, category }) => {
return (
<div key={id} className="post">
<div className="header">
<a>
<img src="https://unsplash.it/40" alt=" title" />
<div>
<span className="detail">Category :{category}</span>
</div>
</a>
</div>
<div className="content">
<p>
{setup}
</p>
<p>
{delivery}
</p>
</div>
<div className="footer">
<ul>
<li>
<a style={{ color: color }} onClick={() => { likePrint(!like); setColor('#2274a5') }}>
<i className="fas fa-heart"></i>
</a>
</li>
<li>
<a>
<i className="fas fa-comment"></i>
</a>
</li>
<li>
<a>
<i className="fas fa-share-alt-square"></i>
</a>
</li>
</ul>
</div>
</div>
);
})}
</div>
);
}
export default PostArea;
Error : Uncaught TypeError: data.posts.map is not a function
I was looking at the response from the https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40, and it seems like it is returning an object, rather an array, which is the expected type of data.post.
I guess you would want to include this object as part of the post array?
const fetchData = async () => {
const result = await axios('https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist&idRange=0-40');
setPost({ posts: [result.data] });
};
i am a new on React and i have a React component as in the next code and i cannot find a way to make the currentLanFlag img src to be dynamic and follow the user choose in the drop down languages menu ......
What i want is : when the user click on the anchor tag German, the img with CLass currentLanFlag to be a German Flag, same for English and the others Languages .
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { translate, Trans } from 'react-i18next';
import de from '../../../assets/img/de.png';
import en from '../../../assets/img/en.png';
import fr from '../../../assets/img/fr.png';
import pt from '../../../assets/img/pt.png';
import ar from '../../../assets/img/ar.GIF';
import '../../../assets/FontAwesome/css/font-awesome.min.css';
import './topNavComponenets.css';
const { version: appVersion } = require('../../../../package.json');
class TopNavComponenets extends Component {
constructor (props) {
super()
this.state = {
firstName: '',
lastName: ''
}
this.logout = this.logout.bind(this)
axios.get('api/auth/en/profile',{ withCredentials: true })
.then(response => this.setState({
firstName: response.data.firstName,
lastName: response.data.lastName,
}));
}
logout () {
axios.get('api/auth/en/logout',{ withCredentials: true })
}
render () {
const { i18n } = this.props;
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);;
};
let currentLanFlag = en;
return (
<div className="topNavComponenets">
<div className='infoContainer row'>
< div className="col-12 text-right">
<div className="userCont col-4">
<Link to="/user" ><i className="fa fa-user" title={"My Profile"}></i></Link>
<p className="infos">
{this.state.firstName} {this.state.lastName}
</p>
</div>
<div className='version col-4'>
<div className="dropdown show">
<a className="dropdown-toggle" href="" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img
className="currentLanFlag"
src={ currentLanFlag }
alt="Language Flag"/>
</a>
<div className="dropdown-menu" aria-labelledby="dropdownMenuLink">
<a onClick={() => changeLanguage('de')} className="dropdown-item"><img className="flag" src={de} alt=""/><Trans>German</Trans></a>
<a onClick={() => changeLanguage('en')} className="dropdown-item"><img className="flag" src={en} alt=""/><Trans>English</Trans></a>
<a onClick={() => changeLanguage('fr')} className="dropdown-item"><img className="flag" src={fr} alt=""/><Trans>French</Trans></a>
<a onClick={() => changeLanguage('pt')} className="dropdown-item"><img className="flag" src={pt} alt=""/><Trans>Portugues</Trans></a>
<a onClick={() => changeLanguage('ar')} className="dropdown-item"><img className="flag" src={ar} alt=""/><Trans>Arabic</Trans></a>
</div>
</div>
<p title={"CMS Version"}>v.{appVersion}</p>
</div>
<div className='buttonContainer col-4'>
<a href="/login"> <span onClick={this.logout}>
<i className="fa fa-power-off" title={"Logout"}></i>
</span></a>
</div>
</div>
</div>
</div>
)}}
export default translate('translations')(TopNavComponenets);
Personally, I would set currentLanFlag in your state.
this.state = {
...
currentLanFlag: 'en'
};
Then change your image tag to be something along the lines of
<img
className="currentLanFlag"
src={ this.state.currentLanFlag }
alt="Language Flag"/>
Your on click should then change the state of this.state.currentLanFlag.
Something along the lines of
// A function
changeLan = (event) {
this.setState({
currentLanFlag: event.target.data
});
changeLanguage(event.target.data);
}
// in your return
<a data='de' onClick={this.changeLan}><img className="flag" src={de} alt=""/><Trans>German</Trans></a>
this.setState will tell react "something changed, rerender" at that point your language flag will be updated to the new flag.
Please note, the above is not tested.
You can find nice documentation here
https://reactjs.org/docs/state-and-lifecycle.html
https://reactjs.org/docs/handling-events.html
Just you need make some minor changes. This is for if you need to switch between two different language.
import en from '../../../assets/img/en.png';
import de from '../../../assets/img/de.png';
1. set the current flag in your state
state = {
currLangFlag: 'en'
}
2. Replace your current event handler with this one
const changeLan = (lng) => {
this.setState({ currLangFlag: lng })
i18n.changeLanguage(lng)
}
3. Use the ternary operator you can switch the flag url after state update
{currLangFlag === 'en' ? <img src={en} alt={currLangFlag} /> : <img src={de} alt={currLangFlag} />}
4. Call the event handler
<NavLink onClick={() => changeLan('en')} to={this.props.location}>
<img className="flag" src={en} alt=""/><Trans>English</Trans>
</NavLink >
<NavLink onClick={() => changeLan('de')} to={this.props.location}>
<img className="flag" src={de} alt=""/><Trans>German</Trans>
</NavLink >