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);
Advertisement
Answer
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.