【问题标题】:ReactJs & Styled components, Can't type anything in the input fieldReactJs 和 Styled 组件,无法在输入字段中输入任何内容
【发布时间】:2021-03-23 22:47:13
【问题描述】:

我正在使用 ReactJs 和样式化组件处理个人项目。

我开始将所有旧的 css 代码改为使用样式组件,但是我也将它应用于输入,但现在它停止工作,我无法在这些输入中输入任何内容。

我尝试再次搜索和阅读 Styled-components Docs,但可惜找不到任何可以解决问题的内容

任何帮助将不胜感激

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);

【问题讨论】:

标签: javascript css reactjs redux styled-components


【解决方案1】:

问题是您的 Styled 输入没有收到您传递的其他属性。在此示例中为 onChangetext。 这里是如何使用传递的道具将属性附加到输入元素的参考。

https://styled-components.com/docs/api#attrs

您还可以在InputForm 中设置输入样式,以避免处理上述问题。这样您就可以继续使用普通的&lt;input /&gt; 元素。

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
    }
  }
`

【讨论】:

  • hmm 我试过第二种方法,但还是不行
  • 您是否将StyledInput 换成了普通的input
  • 是的,当然,我保留了 onChangetype 原样
  • onChange 函数是否被调用?
【解决方案2】:

实际上,无论何时引入更改,组件都会重新渲染,从而导致输入为空,而不管重新渲染之前的更改是什么。

为了解决这个问题,样式化组件的定义应位于render 函数之外。
请检查 this CodeSandbox 以获取您的代码的完整工作演示,只需进行此简单更改。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 2021-09-09
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2018-02-15
    • 2016-01-04
    相关资源
    最近更新 更多