使用状态或道具从父组件更改子组件中输入元素的样式

时间:2017-04-11 03:11:07

标签: reactjs

我正在研究如何通过从父组件传递新类作为prop来更新我的子组件( UpdateInputBox )中的输入元素的边框 - TextInput )。如果我检查输入元素,我可以看到新类被添加到输入元素但样式没有更新。

我有一种感觉,这是因为我的子组件可能无法渲染道具更改。

以下代码:

JSX档案

  import React from 'react';
    import styles from './styles.scss';

    export default class TextInput extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                selectedStateForText: 'textInputNonFocussed'
            }
            this.changeInputState = this.changeInputState.bind(this);
    }

    changeInputState(e) {
        this.setState({
            selectedStateForText: e.target.value,
        });
    }

    render() {
        return (
                <h1>Individual input Test Component</h1>
                <UpdateInputBox updateClass={this.state.selectedStateForText}/>
                <form className='textInputStyleSelector' onChange={this.changeInputState.bind(this)}>
                    <input type='radio' name='class' value='textInputNonFocussedValid' checked={this.state.selectedStateForText === 'textInputNonFocussedValid'} />Non-Focussed Valid
                    <input type='radio' name='class' value='textInputFocussedValid' checked={this.state.selectedStateForText === 'textInputFocussedValid'} />Focussed Valid
                    <input type='radio' name='class' value='textInputNonFocussedInvalid' checked={this.state.selectedStateForText === 'textInputNonFocussedInvalid'} />Non-Focussed Invalid
                </form>

            </div>
        );
    }
}

class UpdateInputBox extends React.Component {
    constructor(props){
        super(props);
        this.state= {
            updateClass: props.updateClass
        }
    }

    render() {
        return (
            <input id='inputStyleComponents' className={this.state.updateClass} placeholder='Label text *' type='text' />
        );
    }
}

样式SCSS文件

$titanium: #686868;
$font-input-placeholder: Regular;
$font-size-small: 12px;
$emerald: #3dc238;
$ruby: #a3403e;

.textInputContainer {
  background-color: white;
}


.inputStyleComponents {
    display: inline-block;
    margin: 10px;
}

// placeholder default css
::-webkit-input-placeholder { /* Chrome/Opera/Safari */
  color: $titanium;
  font-family: $font-input-placeholder;
  font-size: $font-size-small;
}
::-moz-placeholder { 
  color: $titanium;
  font-family: $font-input-placeholder;
  font-size: $font-size-small;
}
:-ms-input-placeholder { 
  color: $titanium;
  font-family: $font-input-placeholder;
  font-size: $font-size-small;
}


// Text Field Non Focussed class (styles can be applied to the input element but defining a class for testing)
input[type=text] {
    border: 1px solid $titanium;
    border-radius: 3px;
    padding: 8px 10px;
    vertical-align: middle;
    outline: none;
}

input[type=text]:focus, .textInputFocussed {
    box-shadow: 0px 0px 5px lavender;
}

.textInputNonFocussedValid {
    box-shadow: 0px 0px 5px $emerald;
}

.textInputFocussedValid {
    box-shadow: 0px 0px 5px springgreen;
}

.textInputNonFocussedInvalid {
    box-shadow: 0px 0px 5px $ruby;
}

.textInputFocussedInvalid {
    box-shadow: 0px 0px 5px crimson;
}

input[type=text]:disabled {
  opacity: 0.5;
  background-color: #fff;
}

input[type=radio] {
  margin: 10px;
}

3 个答案:

答案 0 :(得分:0)

检查scss文件中的类名。我没有看到为类textInputNonFocussed定义的任何规则。尝试使用您要应用的样式为此类定义规则。

例如:

input.textInputNonFocussed {
    color: gray;
}

这可以解决问题,因为您已经提到添加了类。

答案 1 :(得分:0)

当您的父组件状态更新时,您的子状态不会像您认为的那样得到更新。 UpdateInputBox构造函数只运行一次,因此UpdateInputBox的状态只会设置一次。您必须根据UpdateInputBox中收到的props更新componentWillReceiveProps州。你必须做类似下面的事情。希望这会有所帮助。

class UpdateInputBox extends React.Component {
constructor(props){
    super(props);
    this.state= {
        updateClass: props.updateClass
    }
}

componentWillReceiveProps(nextProps) {
 if(this.props.updateClass !== nextProps.updateClass) {
   this.setState({updateClass: nextProps.updateClass});
 }
}

render() {
    return (
        <input id='inputStyleComponents' className={this.state.updateClass} placeholder='Label text *' type='text' />
    );
}

}

答案 2 :(得分:0)

@Panther:

React Lifecycle hook帮助我获取更新的值。我必须对代码进行一些额外的更改,因为我正在导入.scss文件并将其存储为样式

import styles from './styles.scss';

因为我必须使用我的classNames:

<input className={styles.textInputFocussedValid} placeholder='Label text *' type='text' /> 

由于我的新类值使用以下状态存储在状态中:

<input className={this.state.updateClass} placeholder='Label text *' type='text' /> 

没有工作(因为它没有与styles.textInputFocussedValid等样式相关联)。

我最终使用JedWatson的类名来创建如下条件:

const updatedClass = classnames(
 { [`${styles.textInputNonFocussedValid}`]: this.props.updateClass === 'textInputNonFocussedValid' },
 { [`${styles.textInputFocussedValid}`]: this.props.updateClass === 'textInputFocussedValid' },
 { [`${styles.textInputNonFocussedInvalid}`]: this.props.updateClass === 'textInputNonFocussedInvalid' },
 { [`${styles.textInputNonFocussedValid}`]: this.props.updateClass === 'textInputNonFocussedValid' },
 { [`${styles.textInputFocussedInvalid}`]: this.props.updateClass === 'textInputFocussedInvalid' },
        );
        return (
            <input id='inputStyleComponents' className={updatedClass} placeholder='Label text *'type='text' />
        );