Update Avatar value from Text feild - reactjs

I am very new with React.JS as well as new for JS. I have to update avatar value from a text field. This is just a small demo project. My target is as below:
It means that if some one has entered Text in
Nick name
Then Avatar Text must be updated. My render method in App.js as below
return (
<div className="App">
<div style={avatarParentContainer}>
<div style={divStyleAvatar}>
</div>
<span style={avatarContainer}>
{avatar}
</span>
</div>
<div>
<Login/>
</div>
</div>
);
Below is my Avatar
avatar= <Avatar
name={this.setState({avatarname:''})}
size="200"
round={true}
style={avatarClass}
/>;
As in above code i have one separate component as
Login
This Login component have Nick Name field as below:
<TextField
hintText="Enter your Nick name"
floatingLabelText="Nick Name"
onChange = {(event,newValue)=>this.setState({nickname:newValue})}
/>
I know this is silly question for expert person but in my case i am struggling with it. Please help me to get rid this issue.

Move state to your App component. Avatar and Login should be a stateless components. Then you can pass function as a prop to Login, and name from state to Avatar component. Something like this (not tested, because I don't have code of these comopnents ;) ):
const Login = ({ onChange }) => (
<TextField
hintText="Enter your Nick name"
floatingLabelText="Nick Name"
onChange = {(event, newValue) => onChange(newValue)}
/>
);
const Avatar = ({ name }) => (
<Avatar
name={name}
size="200"
round={true}
style={avatarClass}
/>
);
And in App:
return (
<div className="App">
<div style={avatarParentContainer}>
<div style={divStyleAvatar}>
<span style={avatarContainer}>
<Avatar name={this.state.avatarname} />
</span>
</div>
<div>
<Login onChange={avatarname => this.setState({avatarname})} />
</div>
);

Related

clear <input> tag value when opening new page from search bar

So I have 2 components. SearchBar.js and ProductDetail.js
The searchBar JS help me to search product from my header. And when clicked it will redirect to another productDetail page. the problem is I got that take a number as the value, when I change it's number and then proceed to search another product. When I got redirected to that productPage, the input value will stay and not reset. How to fix this ?
Here's my code :
ProductDetail.js
const [productCount, setproductCount] = useState(0);
<input
type="number"
className='input-quantity'
value={productCount || 1}
onChange={(e) => {
setproductCount(parseInt(e.target.value))
}}
/>
SearchBar.js
<div className="searchInput">
<input
id="searchKeyInputId"
type="text"
placeholder={placeholder}
onChange={handleFilter}
ref={inputRef}
/>
<BiSearch className="input-append-icon" />
{filteredData.length !== 0 && (
<div className="searchResult">
{filteredData && filteredData.slice(0, 5).map((value) => {
return <Link
to={`/p/${value.id}/${value.slug}`}
className="searchItem"
key={value.id}
onClick={clearInput}
>
<p className='fontRegular'>{value.name}</p>
</Link>
})}
</div>
)}
</div>

Input field not cleared after using useState with onClick

I have a React app, where I'm using an input field as a searchbar, which upon typing, returns a list of products, and upon clicking any product takes you to that product page. I want to clear the typed text in the searchbar after the redirection to new page has happened but I haven't been able to achieve this yet.
I've tried many methods and went over similar posts, but I don't know what am I doing wrong as text is never cleared.
I'm using Material UI for rendering the list and have imported everything as needed.
Below is my code:
Navbar component (contains searchbar)
const Navbar = () => {
const [text, setText] = useState('');
const [liopen, setLiopen] = useState(true);
const getText = (text) => {
setText(text);
setLiopen(false);
};
const handleClick2 = (e) => {
setText('');
setLiopen(true)
};
return (
<header>
<nav>
<div className="middle">
<div className="nav_searchbar">
<span className="search_icon">
<SearchIcon id="search" />
</span>
<input
type="text"
onChange={(e) => getText(e.target.value)}
name=""
placeholder="Search for products, categories, ..."
id=""
/>
</div>
{text && (
<List className="extrasearch" hidden={liopen}>
{products
.filter((product) =>
product.title.toLowerCase().includes(text.toLowerCase())
)
.map((product) => (
<ListItem>
<NavLink
to={`/getproductsone/${product.id}`}
onClick={(e) => {handleClick2(e)}}
>
{product.title}
</NavLink>
</ListItem>
))}
</List>
)}
</nav>
</div>
</header>
);
};
export default Navbar;
You need to set the value of the input if you want it controlled by the component state.
<input value={text}
type="text"
onChange={(e) => getText(e.target.value)}
name=""
placeholder="Search for products, categories, ..."
id=""
/>

Show hide multiple password in react js

I'm currently learning React js. My code work when it has one show hide password. But when i have more than one, i have struggle. This code work, because it has just one.
export default function App() {
const [changePassword, setChangePassword] = useState(true);
const changeIcon = changePassword === true ? false : true;
return (
<div className="wrapper-login">
<div className="wrapper-form">
<h2>Welcome Back!</h2>
<form>
<label>Email</label>
<div>
<input
type="email"
name="email"
required
/>
</div>
<label>Password</label>
<div className="form-group">
<input
type={changePassword ? "password" : "text"}
name="password"
required
/>
<span className="icon"
onClick={() => {
setChangePassword(changeIcon);
}}
>
{changeIcon ? <EyeOutlined /> : <EyeInvisibleOutlined />}
</span>
</div>
</form>
</div>
</div>
);
}
In codesandbox i have 3 input type password, and each input have show hide password. Can you help me to achieved that ? and explain to me why thats work ? . I'm sorry for my bad English. Thank you
You may create a component that controls hide or show behavior. For example, you can create a generic component for isolated show hide behavior. You pass the input name, and it creates a sub-component for you.
export default function ShowHidePassword({ name }) {
const [isVisible, setVisible] = useState(false);
const toggle = () => {
setVisible(!isVisible);
};
return (
<div className="form-group">
<input type={!isVisible ? "password" : "text"} name={name} required />
<span className="icon" onClick={toggle}>
{isVisible ? <EyeOutlined /> : <EyeInvisibleOutlined />}
</span>
</div>
);
}
usage:
<div>
<ShowHidePassword name="name" />
<ShowHidePassword name="password" />
</div>
when you use one state for more than one thing, state changes will effect on all of elements that use the state.
best way is create a reusable input component and import it anywhere and As much as you want. on this way every changes will happen just inside that component and wont effect on others component
dont forget to pass ...props to your input if you want access to the input onChange,name and ....
export const PasswordInput = (props) => {
const [hide, setHide] = useState(false);
const toggle = () => {
setHide((prev) => !prev);
};
return (
<div>
<input type={!isVisible ? "password" : "text"} {...props} required />
<i className="icon" onClick={toggle}>
{hide ? <EyeVisible /> : <EyeInvisible />}
</i>
</div>
);
}
usage:
<div>
<PasswordInput />
<PasswordInput />
<PasswordInput />
</div>
now every toggle will only effect on the clicked input and there is no side effect and re render

React Router v6 Button onclick Navigate vis class components

Trying to port an application from router v2 to router v6.
Everything I see everywhere is hooks.
Tried to make a custom withRouter, "Hooks can only be called inside of the body of a function component."
The button in question
<YAButton
onClick={this.goToForgotPassword.bind(this)}
size="tiny"
style={YALogin.styles.forgotPassword}
type="text"
>
the function it calls
goToForgotPassword() {
this.props.navigate(`/forgot${isEmail(this.state.emailAddress) ?
`?emailAddress=${encodeURIComponent(this.state.emailAddress)}` :
''
}`);
}
the export at the bottom of the jsx file, perhaps something is amiss here?
export default connect(YALogin.mapStateToProps, YALogin.mapDispatchToProps)(Radium(withRouter(YALogin)));
and my withRouter
export const withRouter = (Component) => {
const Wrapper = (props) => {
const location = useLocation();
const navigate = useNavigate();
const params = useParams();
return (
<Component
{...props}
navigate={navigate}
location={location}
params={params}
/>
);
};
return Wrapper;
};
Clearly I can't use hooks, but I also can't change the entire application over to function based components.
How do click "Forgot Password" button to go the
`/forgot${isEmail(this.state.emailAddress) ?
`?emailAddress=${encodeURIComponent(this.state.emailAddress)}` :
''
}`
edit: The render().
render() {
return (
<main
className="splash"
style={{
backgroundImage: `url(${window.__configuration.cdn}/splash/splash.jpg)`
}}
>
<form
className="stripped"
onSubmit={this.sendLoginRequest.bind(this)}
>
{/* Render the application logo */}
<div className="dual-logo">
<img
src={`${window.__configuration.cdn}/logos/logo-redacted-y-negative.svg`}
className="redacted-logo"
alt="Weemarkable"
/>
<div className="logo-divider"></div>
<img
src={`${window.__configuration.cdn}/logos/logo-weemarkable-negative-${Translator.getLang()}.svg`}
className="weemarkable-logo"
alt="Weemarkable"
/>
</div>
{/* Set inner html to allow non-breaking-space tags to render */}
<p className="tagline"
dangerouslySetInnerHTML={{__html: Translator.translate("General.Tagline")}}></p>
<fieldset>
{/* Render an alert if the login has failed for any reason */}
{
this.props.loginError !== null ?
<YAAlert type="E">
<span>{this.state.errorMessage}</span>
</YAAlert> :
null
}
{/* Collect the email address from the user */}
<YAInput
type="email"
className="stripped-input"
noBaseStyles
onChange={this.onChange.bind(this, 'emailAddress')}
placeholder={Translator.translate("General.YourEmail")}
value={this.state.emailAddress}
/>
{/* Collect the password from the user */}
<YAInput
type="password"
className="stripped-input"
noBaseStyles
onChange={this.onChange.bind(this, 'password')}
placeholder={Translator.translate("Password.Password")}
value={this.state.password}
/>
<div style={YALogin.styles.controls}>
{/* Button which submits the login request to the server */}
<div>
<YAInput
type="submit"
className={classNames('btn-stripped', {disabled: !this.isFormValid()})}
noBaseStyles
value={Translator.translate("MainPage.SignIn")}
/>
</div>
{/* Button which takes the user to the forgot password screen */}
<div>
<YAButton
onClick={() => useNavigate()(`/forgot${isEmail(this.state.emailAddress) ? `?emailAddress=${encodeURIComponent(this.state.emailAddress)}` : ''}`)}
size="tiny"
style={YALogin.styles.forgotPassword}
type="text"
>
{Translator.translate("MainPage.ForgotPassword")}
</YAButton>
|
<YAButton
onClick={this.goToForgotPassword.bind(this)}
size="tiny"
style={YALogin.styles.forgotPassword}
type="text"
>
{Translator.translate("MainPage.TOU")}
</YAButton>
</div>
</div>
</fieldset>
</form>
{/* Render footer logo */}
<footer className="brand-bar login">
<img
src={`${window.__configuration.cdn}/logos/logo-redacted-of-hamilton-${window.__configuration.langCode}.svg`}
className="footer-logo"
alt="redactedof redacted| redacted| Brantford"
/>
</footer>
</main>
);
}
}

How can I search Giphy's GIF live with React.js?

Based on the official Giphy demo(CodeSandBox), I would like to create a live search function for Giphy GIFs.
And below is a demo of it.
search demo(CodeSandBox)
It holds the keyword as state and passes the keyword state to the search method of giphyFetch.
But the search results are not displayed.
Is there a problem with the code in the demo, or a solution to this problem?
Thank you.
source code
const giphyFetch = new GiphyFetch("sXpGFDGZs0Dv1mmNFvYaGUvYwKX0PWIh");
function App() {
const [keyword, setKeyword] = useState("");
const fetchGifs = (offset: number) =>
giphyFetch.search(keyword, { offset, limit: 10 });
return (
<>
<p>
<img src="./logo.gif" width="200" alt="Powered by GIPHY" />
</p>
<p>
input keyword
<input type="text" onChange={e => setKeyword(e.target.value)} />
</p>
<h4>search result</h4>
<Carousel fetchGifs={fetchGifs} gifHeight={200} gutter={6} />
</>
);
}
The Carousal does the fetchGifs once upon mount. So you need to force re-mount upon your input onChange. You can do this by adding dynamic key
Like this
...
<>
<p>
<img src="./logo.gif" width="200" alt="Powered by GIPHY" />
</p>
<p>
input keyword
<input
value={keyword}
type="text"
onChange={e => setKeyword(e.target.value)}
/>
</p>
<h4>search result</h4>
<Carousel
key={keyword}
fetchGifs={() => fetchGifs(5)}
gifHeight={200}
gutter={6}
/>
</>
...
Working demo is here

Resources