Reputation: 67
I'm working on personal project using ReactJs & styled Components.
I started to move all old css code to use styled-components instead, however I applied it on the Inputs as well, but now it stopped working and I can't type anything in these inputs.
I tried to search and read Styled-components Docs again, but alas couldn't find anything that can solve the issue
any help would be appreciated
import React, { Component } from 'react';
import Info from '@material-ui/icons/Info'
import Constants from '../../constants/Constants'
import {bindActionCreators} from 'redux'
import * as actions from '../../redux/actions/actionCreators.js';
import {connect} from 'react-redux'
import {Redirect} from 'react-router-dom'
import styled from 'styled-components'
class Login extends Component {
constructor(props) {
super(props)
this.handleUsernameInput = this.handleUsernameInput.bind(this)
this.handlePasswordInput = this.handlePasswordInput.bind(this)
this.state = {
username: null,
password: null,
validationErrorExsist: false,
validationErrorText: null,
isAuthenticated: this.props.isAuth
}
}
GetErrorText = () => {
// username field is empty
if(this.state.username == null) this.setState({ validationErrorText: Constants.VALIDATION_TEXT.EMPTY_USERNAME_FEILD })
// password field is empty
else if(this.state.password == null) this.setState({ validationErrorText: Constants.VALIDATION_TEXT.EMPTY_PASSOWRD_FEILD })
}
handleUsernameInput = (event) => {
this.setState({username: event.target.value})
}
handlePasswordInput = (event) => {
this.setState({password: event.target.value})
}
login = () => {
if((this.state.username == null || this.state.password == null)) {
this.setState({validationErrorExsist: true}, () => {
return this.GetErrorText()
})
}
else {
return this.props.loginUser(this.state.username, this.state.password)
}
}
render() {
/** Login Styles Go Here */
const LoginContainer = styled.div`
padding: 10px;
margin: 40px auto;
width: 80%;
`
const LoginText = styled.div`
font-size: 1.5em;
font-weight: 600;
margin-bottom: 20px;
`
const NoticeText = styled.div`
line-height: 20px;
margin-bottom: 16px;
`
const LoginButtonContainer = styled.div`
display: flex;
justify-content: flex-star;
margin-top: 18px;
`
const LoginButton = styled.div`
border-color: #01b4e4;
background-color: #01b4e4;
color: #fff;
padding: .675rem .95rem;
border-radius: 5px;
font-weight: bold;
border-radius: 14px;
&:hover {
cursor: pointer;
}
`
const CreateNewAccountLink = styled.a`
color: #00c6ff;
`
const LabelName = styled.div`
font-weight: bold;
margin-top: 15px;
`
const InputForm = styled.div`
display: flex;
flex-direction: column;
`
const StyledInput = styled.input`
margin-top: 10px;
border-color: rgba(33,37,41,0.15);
color: #292b2c;
padding: 12px;
border-radius: .25rem;
line-height: 1.5;
vertical-align: middle;
&:focus {
outline: none
}
`
const ErrorCardContainer = styled.div`
margin: 20px 0 10px 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
background-color: #fff;
border-radius: 8px;
border: 1px solid #ccc;
`
const ErrorCardHeader = styled.div`
background-color: #d53540;
color: #fff;
display: flex;
padding: 20px;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
`
const ErrorText = styled.div`
font-weight: 600;
font-size: 1.2em;
line-height: 1.2em;
margin-left: 5px;
`
const ErrorTypeContainer = styled.div`
padding: 5px;
`
const StyledUnorderedList = styled.ul`
line-height: 1.4;
`
if(this.state.isAuthenticated) return <Redirect to='/' />
const {validationErrorExsist} = this.state
const ErrorStatusCard = () => (
<ErrorCardContainer>
<ErrorCardHeader>
<Info />
<ErrorText>There was a problem!</ErrorText>
</ErrorCardHeader>
<ErrorTypeContainer>
<StyledUnorderedList>
<li>{this.state.validationErrorText}</li>
{/* TODO: login attemps */}
{/* <li>You have 10 remaining login attempts.</li> */}
</StyledUnorderedList>
</ErrorTypeContainer>
</ErrorCardContainer>
)
return (
<LoginContainer>
<LoginText>Login to your account</LoginText>
<NoticeText>
This app gets its data from the TMDD APIs. To view your account information, login with your TMDb credentials in the form below. To create one,
<CreateNewAccountLink href="https://www.themoviedb.org/signup" target="_blank"> Click here</CreateNewAccountLink>
</NoticeText>
{validationErrorExsist && <ErrorStatusCard />}
<InputForm>
<LabelName>Username</LabelName>
<StyledInput onChange={this.handleUsernameInput} type="text"/>
</InputForm>
<InputForm>
<LabelName>Password</LabelName>
<StyledInput onChange={this.handlePasswordInput} type="password"/>
</InputForm>
<LoginButtonContainer>
{/* <div className="login-btn" onClick={this.login}>Login</div> */}
<LoginButton onClick={this.login}>Login</LoginButton>
</LoginButtonContainer>
</LoginContainer>
);
}
}
const mapStateToProps = (state) => {
return {
isAuth: state.isAuth,
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(actions, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
Upvotes: 2
Views: 3023
Reputation: 5138
What you're experiencing is actually the components being re-rendered whenever a change is introduced, resulting in empty inputs, regardless of what the change was before the re-render.
In order to resolve this, the styled components' definitions should reside outside the render
function.
Please check this CodeSandbox for a full working demo of your code, with this simple change.
Upvotes: 2
Reputation: 1047
The issue is that your Styled inputs aren't receiving the additional attributes that you are passing. In this example onChange
and text
.
Here is the reference of how to use use the passed props to attach the attributes to the input element.
https://styled-components.com/docs/api#attrs
You can also style your input inside your InputForm
to avoid dealing with the mentioned issue above. This way you can just keep using the normal <input />
element.
const InputForm = styled.div`
display: flex;
flex-direction: column;
input {
margin-top: 10px;
border-color: rgba(33,37,41,0.15);
color: #292b2c;
padding: 12px;
border-radius: .25rem;
line-height: 1.5;
vertical-align: middle;
&:focus {
outline: none
}
}
`
Upvotes: 0